我需要显示长文本,它将占据多个屏幕/页面。我还必须添加一些功能,因此我想实现自己的文本显示组件。
我发现了两个与此任务相对应的类:
TextPainter
将 TextSpan 用于文本
使用 paint(canvas,offset)绘画
段落
为文字和样式使用“队列”
使用 Canvas.drawParagraph(paragraph,offset)绘画
它们和要使用的是什么?!
如果文本包含100行,并且页面上只能放置10行,那么如何在下一页上绘制被截断的文本,直到没有剩余?
答案 0 :(得分:0)
tl; dr:imo TextPainter
> Paragraph
(由于API更好)。
我创建了simple example app,以比较TextPainter
和Paragraph
在CustomPainter
的{{3}}上呈现文本的方法。两种方法都非常好,都使用了不同的方法,都存在奇怪的摆动。
TextPainter
首先,我想提一下TextPainter
界面似乎更容易-至少对我而言。您只需要指定text
作为Canvas
条目或树,并且-很奇怪,这不是默认设置-textDirection
。您还可以提供诸如maxLines
,style
和textAlign
等选项。然后,您需要使用layout
来指定渲染的放置方式(仅maxWidth
)。最后,在指定的paint
上某些Canvas
上的Offset
。
final TextPainter textPainter = TextPainter(
text: TextSpan(text: text, style: style),
textAlign: TextAlign.justify,
textDirection: TextDirection.ltr
)
..layout(maxWidth: size.width - 12.0 - 12.0);
textPainter.paint(canvas, const Offset(12.0, 36.0));
使用过的TextSpan
在Flutter上非常普遍-RichText
和其他小部件也在使用此类。我还必须注意,使用 TextPainter
可以检查height
和width
以像素为单位的文本(在渲染之前)。
Paragraph
第二:Paragraph
。这似乎是更基础的程序方法。如下所示,Paragraph
方法不太干净。首先,您必须使用ParagraphBuilder
(因为Paragraph
没有构造函数)。您需要用TextSpan
来填充它,其中包含各种文本样式,例如字体信息,textAlign
,maxLines
等。然后,您可以使用pushStyle
,pop
和addText
准备该段落的下一部分和下一部分。 build
之后,您将获得Paragraph
,您可以在drawParagraph
上Canvas
。
final ui.ParagraphBuilder paragraphBuilder = ui.ParagraphBuilder(
ui.ParagraphStyle(
fontSize: style.fontSize,
fontFamily: style.fontFamily,
fontStyle: style.fontStyle,
fontWeight: style.fontWeight,
textAlign: TextAlign.justify,
)
)
..pushStyle(style.getTextStyle())
..addText(text);
final ui.Paragraph paragraph = paragraphBuilder.build()
..layout(ui.ParagraphConstraints(width: size.width - 12.0 - 12.0));
canvas.drawParagraph(paragraph, const Offset(12.0, 36.0));
请注意,TextStyle
有两种类型(Dart UI和Flutter)。与pushStyle
一致,您可以看到ParagraphStyle
被转换为Flutter Painting library TextStyle
。另一个奇怪的事情是,即使您将在后面的行中使用ParagraphBuilder
,也可以仅在pushStyle
中指定一些字体设置。并且layout
必须用width
指定。
我认为在读取文件(尤其是格式化文件)的情况下,我会更好,因为不需要将文件解析为TextSpan
树,这可能会很昂贵。我想如果您知道自己在做什么,它的速度也可能比其他方法快一点,但是我没有时间对此进行深入研究。
当文本过多时,您可能希望将其剪切。 Paragraph
和TextPainter
都以一种或另一种方式公开maxLines
-设置最大行数和didExceedMaxLines
-以检测是否超出了限制。还有canvas.clipRect
和相关方法,可以将所有图形剪切到选定的空间中。
还有一个简单的Dart UI TextStyle
(发布时),表明这两种方法是可比的(在我的测试案例中,TextPainter
比Paragraph
快2%)。可能也是测量误差¯\ _(ツ)_ /¯。