dart Flutter:如何获取文本行数

bvk5enib  于 2023-05-11  发布在  Flutter
关注(0)|答案(6)|浏览(406)

如何获取文本行数在我们的Flutter项目中,我们需要确定文本行数是否超过3,然后我们会显示提示信息。我们如何使用代码来实现它?

wfsdck30

wfsdck301#

如果您只是想知道文本包含多少内部行,可以执行一个简单的

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

然而,我猜您更感兴趣的是实际上可视化显示的行数。在这里,事情变得有点复杂,因为您需要知道可用空间(BoxConstraints),以便计算文本需要多少行。为此,您可以使用LayoutBuilder来延迟小部件构建,并使用TextPainter来执行实际计算:

return LayoutBuilder(builder: (context, constraints) {
  final span = TextSpan(text: yourText, style: yourStyle);
  final tp = TextPainter(text: span, textDirection: TextDirection.ltr);
  tp.layout(maxWidth: constraints.maxWidth);
  final numLines = tp.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中提取了一些代码,您可能也会感兴趣:它调整文本的大小,使其适合给定的空间。
无论如何,在显示提示时要小心:您的小部件的build方法可能会在一秒钟内被调用多次,从而导致同时显示多个提示。
注意:computeLineMetrics()函数是在答案的初始版本之后添加的。这就是为什么这个答案的前一个版本使用TextPainter(text: span, maxLines: 3),然后检查是否为tp.didExceedMaxLines

e4yzc0pl

e4yzc0pl2#

现在很容易找到一个段落的行数:

import 'dart:ui' as ui;

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

注意事项

  • computeLineMetrics必须在布局后调用。
  • 我有另一个答案,我保留了历史的目的,因为我需要链接到它在解释的变化。

参见

lstz6jyr

lstz6jyr3#

更新:这个答案是出于历史目的。参见my updated answer here以获得更简单的解决方案。

如果你有一个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方法,但我还没有找到它。

iszxjhcz

iszxjhcz4#

我只是得到了这段代码的支持,因此这就是我如何验证它是否穿过最大线

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
hgtggwj0

hgtggwj05#

在我的情况下,我需要得到的行数来改变它的基础上的高度,而是我使用堆栈部件作为一个工作。下面是我的代码:

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),),
                        )
                      ],
                    ),
                  ),
eagi6jfj

eagi6jfj6#

只需放置属性maxLines:null和TextInputAction.done,如果您希望将新行限制为特定的限制计数“\n”。

相关问题