Flutter:在截断 Flutter 中的文本小部件之前获取最后一个字

Flutter: Get last word before truncation for Text Widget in Flutter

我有一个多行正文,我想将其拆分到多个屏幕。我正在使用带有溢出 属性 的文本小部件,如下所示:

Text(
    body,
    style: Theme.of(context).textTheme.bodyText2,
    maxLines: 8,
    overflow: TextOverflow.ellipsis,
  );

现在,在下一页上,我想从上一页被截断的单词开始正文。例如,对于正文 'Hello, nice to meet you all. Hope you have a good day!',它应该是这样的:

第 1 页:

Hello, nice to meet you all. Hope...

第 2 页:

...you have a good day!

现在,我正在尝试为文本小部件找到一种方法来告诉我它在第 1 页上截断文本的位置。有人对如何处理有任何建议吗?

我找到了我正在寻找的答案。这是使用 TextPainter 的 computeLineMetrics 方法的一种巧妙方法。原始来源:SplittedText

具体而言,以下代码很有帮助:

import 'dart:ui';
import 'package:flutter/cupertino.dart';

abstract class SplittedText {
  List<String> getSplittedText(Size pageSize, TextStyle textStyle, String text);
}

class SplittedTextImpl extends SplittedText {
  @override
  List<String> getSplittedText(
      Size pageSize, TextStyle textStyle, String text) {
    final List<String> _pageTexts = [];
    final textSpan = TextSpan(text: text, style: textStyle);
    final textPainter = TextPainter(
      text: textSpan,
      textDirection: TextDirection.ltr,
    );
    textPainter.layout(
      minWidth: 0,
      maxWidth: pageSize.width,
    );

    // https://medium.com/swlh/flutter-line-metrics-fd98ab180a64
    List<LineMetrics> lines = textPainter.computeLineMetrics();
    double currentPageBottom = pageSize.height;
    int currentPageStartIndex = 0;
    int currentPageEndIndex = 0;

    for (int i = 0; i < lines.length; i++) {
      final line = lines[i];

      final left = line.left;
      final top = line.baseline - line.ascent;
      final bottom = line.baseline + line.descent;

      // Current line overflow page
      if (currentPageBottom < bottom) {
        // 
        currentPageEndIndex =
            textPainter.getPositionForOffset(Offset(left, top)).offset;
        final pageText =
            text.substring(currentPageStartIndex, currentPageEndIndex) ?? "";
        _pageTexts.add(pageText);

        currentPageStartIndex = currentPageEndIndex;
        currentPageBottom = top + pageSize.height;
      }
    }

    final lastPageText = text.substring(currentPageStartIndex) ?? "";
    _pageTexts.add(lastPageText);
    return _pageTexts;
  }
}