Flutter: How to Get the Number of Text Lines

旧街凉风 提交于 2019-12-19 02:38:08

问题


How to Get the Number of Text Lines In our Flutter project, we need to determine if the number of lines of text exceeds 3, then we will display a prompt message. How can we use the code to implement it?


回答1:


If you simply want to check for how many newlines the text contains, you can do a simple

final numLines = '\n'.allMatches(yourText).length + 1;

However, I guess you're more interested in the number of lines that are actually being displayed visually. Here, things get a little more complicated, because you need to know the available space (the BoxConstraints) in order to calculate how many lines the text needs. To do that, you can use a LayoutBuilder to delay the widget building and a TextPainter to do the actual calculation:

return LayoutBuilder(builder: (context, size) {
  final span = TextSpan(text: yourText, style: yourStyle);
  final tp = TextPainter(text: span, maxLines: 3);
  tp.layout(maxWidth: size.maxWidth);

  if (tp.didExceedMaxLines) {
    // The text has more than three lines.
    // TODO: display the prompt message
    return Container(color: Colors.red);
  } else {
    return Text(yourText, style: yourStyle);
  }
});

I extracted some of the code from the auto_size_text pub package, which might also be interesting to you: It sizes its text so it fits in the given space.

Anyhow, be careful when displaying the prompt: Your widget's build method may be called several times per second, resulting in multiple prompts being displayed simultaneously.




回答2:


If you have a TextPainter object and you have already called layout, then you can get the number of lines by selecting everything and calling getBoxesForSelection. Each box is the size of the line.

TextSelection selection = TextSelection(baseOffset: 0, extentOffset: text.length);
List<TextBox> boxes = textPainter.getBoxesForSelection(selection);
int numberOfLines = boxes.length;

Here is an example:

final text = 'My text line.\nThis line wraps to the next.\nAnother line.';

print(numberOfLines); // 4

Unfortunately, this fails if there is a mix of bidirectional text:

final text = 'My text line.\nThis كلمة makes more boxes.\nAnother line.';

print(numberOfLines); // 6

This could be overcome by only counting the boxes that along one edge. If you notice the data from above, there are only four boxes that have an edge at 0.0.

flutter: TextBox.fromLTRBD(0.0, 0.2, 171.8, 36.0, TextDirection.ltr)
flutter: TextBox.fromLTRBD(0.0, 36.5, 68.4, 72.3, TextDirection.ltr)
flutter: TextBox.fromLTRBD(68.4, 38.2, 111.5, 75.0, TextDirection.rtl)
flutter: TextBox.fromLTRBD(111.5, 36.5, 299.9, 72.3, TextDirection.ltr)
flutter: TextBox.fromLTRBD(0.0, 77.2, 92.2, 113.0, TextDirection.ltr)
flutter: TextBox.fromLTRBD(0.0, 113.2, 179.7, 149.0, TextDirection.ltr)

I wish there were a TextPainter.numberOfLines method, but I haven't found it.

Update:

There is a proposal to add this functionality.




回答3:


It is now easy to find the number of lines in a paragraph:

List<ui.LineMetrics> lines = textPainter.computeLineMetrics();
int numberOfLines = lines.length;

Notes

  • computeLineMetrics must be called after layout.
  • This change is current as of the latest master branch in the Flutter repo. I don't know how long it will take to get into the stable channel.
  • I had another answer which I am keeping for historical purposes because I need to link to it in an explanation of the change.


来源:https://stackoverflow.com/questions/54091055/flutter-how-to-get-the-number-of-text-lines

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!