Flutter:如何获取文本行数
Flutter: How to Get the Number of Text Lines
如何获取文本行数
在我们的Flutter项目中,我们需要判断文本的行数是否超过3,然后我们会显示一个提示信息。我们如何使用代码来实现它?
如果你只是想知道文本包含多少行,你可以做一个简单的
final numLines = '\n'.allMatches(yourText).length + 1;
不过,我猜您更感兴趣的是实际在视觉上显示的行数。
在这里,事情变得有点复杂,因为您需要知道可用的 space(BoxConstraints
)才能计算文本需要多少行。
为此,您可以使用 LayoutBuilder
来延迟小部件构建,并使用 TextPainter
来进行实际计算:
return LayoutBuilder(builder: (context, constraints) {
final span = TextSpan(text: yourText, style: yourStyle);
final tp = TextPainter(text: span);
tp.layout(maxWidth: constraints.maxWidth);
final numLines = textPainter.computeLineMetrics().length;
if (numLines > 3) {
// TODO: display the prompt message
return ColoredBox(color: Colors.red);
} else {
return Text(yourText, style: yourStyle);
}
});
我从 auto_size_text
pub package 中提取了一些代码,您可能也会感兴趣:
它调整其文本的大小,使其适合给定的 space.
总之,显示提示时要小心:
您的小部件的 build
方法可能每秒被调用多次,导致同时显示多个提示。
注:computeLineMetrics()
功能是在最初版本的回答后添加的。这就是为什么此答案的先前版本使用 TextPainter(text: span, maxLines: 3)
然后检查是否 tp.didExceedMaxLines
.
更新:这个答案是为了历史目的。请参阅 以获得更简单的解决方案。
如果您有一个 TextPainter
对象并且您已经调用了 layout
,那么您可以通过选择所有内容并调用 getBoxesForSelection
来获取行数。每个方框都是线的大小。
TextSelection selection = TextSelection(baseOffset: 0, extentOffset: text.length);
List<TextBox> boxes = textPainter.getBoxesForSelection(selection);
int numberOfLines = boxes.length;
这是一个例子:
final text = 'My text line.\nThis line wraps to the next.\nAnother line.';
print(numberOfLines); // 4
不幸的是,如果存在双向文本混合,此操作将失败:
final text = 'My text line.\nThis كلمة makes more boxes.\nAnother line.';
print(numberOfLines); // 6
这可以通过仅计算沿着一条边的框来解决。如果您注意到上面的数据,只有四个框的边为 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)
我希望有一个 TextPainter.numberOfLines
方法,但我没有找到它。
现在很容易找到一个段落中的行数:
List<ui.LineMetrics> lines = textPainter.computeLineMetrics();
int numberOfLines = lines.length;
备注
computeLineMetrics
必须在布局后调用。
- 我保留了另一个答案以供历史参考,因为我需要 link 解释更改。
另见
我刚得到这段代码的支持,因此这就是我验证它是否超过最大线数的方式
var text="Clita takimata dolor diam magna aliquyam et sed dolores sadipscing. Sed ut
diam rebum labore sadipscing sit amet, diam labore.";
final span=TextSpan(text:text);
final tp =TextPainter(text:span,maxLines: 3,textDirection: TextDirection.ltr);
tp.layout(maxWidth: MediaQuery.of(context).size.width); // equals the parent screen width
print(tp.didExceedMaxLines);
//false for maxlines 3
//true for maxlines 1
在我的例子中,我需要获取行数以根据它更改高度,但我使用 Stack 小部件作为解决方法。
这是我的代码:
Container(
height: AppTheme.fullHeight(context) *.08,
child: Stack(
children: [
Container(
height: AppTheme.fullHeight(context) *.08,
child: Text(
"${products[index].name!}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12,color: Utils.secondaryColor),),
),
//SizedBox(height: MediaQuery.of(context).size.height * .01,),
Positioned(
bottom: AppTheme.fullHeight(context) *.0,
left: 0,
child: Text(
products[index].price! + Constants.CURRENCY.tr,
style: TextStyle(fontSize: 16,
fontWeight: FontWeight.bold,color: Utils.secondaryColor),),
)
],
),
),
只需放置 属性 maxLines: null 和 TextInputAction.done,如果您想将新行限制为特定的限制计数 "\n" 。
如何获取文本行数 在我们的Flutter项目中,我们需要判断文本的行数是否超过3,然后我们会显示一个提示信息。我们如何使用代码来实现它?
如果你只是想知道文本包含多少行,你可以做一个简单的
final numLines = '\n'.allMatches(yourText).length + 1;
不过,我猜您更感兴趣的是实际在视觉上显示的行数。
在这里,事情变得有点复杂,因为您需要知道可用的 space(BoxConstraints
)才能计算文本需要多少行。
为此,您可以使用 LayoutBuilder
来延迟小部件构建,并使用 TextPainter
来进行实际计算:
return LayoutBuilder(builder: (context, constraints) {
final span = TextSpan(text: yourText, style: yourStyle);
final tp = TextPainter(text: span);
tp.layout(maxWidth: constraints.maxWidth);
final numLines = textPainter.computeLineMetrics().length;
if (numLines > 3) {
// TODO: display the prompt message
return ColoredBox(color: Colors.red);
} else {
return Text(yourText, style: yourStyle);
}
});
我从 auto_size_text
pub package 中提取了一些代码,您可能也会感兴趣:
它调整其文本的大小,使其适合给定的 space.
总之,显示提示时要小心:
您的小部件的 build
方法可能每秒被调用多次,导致同时显示多个提示。
注:computeLineMetrics()
功能是在最初版本的回答后添加的。这就是为什么此答案的先前版本使用 TextPainter(text: span, maxLines: 3)
然后检查是否 tp.didExceedMaxLines
.
更新:这个答案是为了历史目的。请参阅
如果您有一个 TextPainter
对象并且您已经调用了 layout
,那么您可以通过选择所有内容并调用 getBoxesForSelection
来获取行数。每个方框都是线的大小。
TextSelection selection = TextSelection(baseOffset: 0, extentOffset: text.length);
List<TextBox> boxes = textPainter.getBoxesForSelection(selection);
int numberOfLines = boxes.length;
这是一个例子:
final text = 'My text line.\nThis line wraps to the next.\nAnother line.';
print(numberOfLines); // 4
不幸的是,如果存在双向文本混合,此操作将失败:
final text = 'My text line.\nThis كلمة makes more boxes.\nAnother line.';
print(numberOfLines); // 6
这可以通过仅计算沿着一条边的框来解决。如果您注意到上面的数据,只有四个框的边为 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)
我希望有一个 TextPainter.numberOfLines
方法,但我没有找到它。
现在很容易找到一个段落中的行数:
List<ui.LineMetrics> lines = textPainter.computeLineMetrics();
int numberOfLines = lines.length;
备注
computeLineMetrics
必须在布局后调用。- 我保留了另一个答案以供历史参考,因为我需要 link 解释更改。
另见
我刚得到这段代码的支持,因此这就是我验证它是否超过最大线数的方式
var text="Clita takimata dolor diam magna aliquyam et sed dolores sadipscing. Sed ut
diam rebum labore sadipscing sit amet, diam labore.";
final span=TextSpan(text:text);
final tp =TextPainter(text:span,maxLines: 3,textDirection: TextDirection.ltr);
tp.layout(maxWidth: MediaQuery.of(context).size.width); // equals the parent screen width
print(tp.didExceedMaxLines);
//false for maxlines 3
//true for maxlines 1
在我的例子中,我需要获取行数以根据它更改高度,但我使用 Stack 小部件作为解决方法。 这是我的代码:
Container(
height: AppTheme.fullHeight(context) *.08,
child: Stack(
children: [
Container(
height: AppTheme.fullHeight(context) *.08,
child: Text(
"${products[index].name!}",
maxLines: 2,
overflow: TextOverflow.ellipsis,
style: TextStyle(fontSize: 12,color: Utils.secondaryColor),),
),
//SizedBox(height: MediaQuery.of(context).size.height * .01,),
Positioned(
bottom: AppTheme.fullHeight(context) *.0,
left: 0,
child: Text(
products[index].price! + Constants.CURRENCY.tr,
style: TextStyle(fontSize: 16,
fontWeight: FontWeight.bold,color: Utils.secondaryColor),),
)
],
),
),
只需放置 属性 maxLines: null 和 TextInputAction.done,如果您想将新行限制为特定的限制计数 "\n" 。