我正在参加「启航方案」。

问题

Text文本设置maxLins特点将文本强制切断之后,Text的承载字符串是切断前?还是切断后的呢?咱们该怎么获取切断后的字符串呢?

答案是:切断前,切断字符串的操作并不会改动Text的真实文本内容特点,无论原生还是Flutter 切断字符串的操作仅仅对TextUI组件的制作区域施加一个约束。

那么咱们需求从源码里看下当咱们设置了maxLine这个特点以后,文本Text究竟是怎么切断显现的, 跟随着源码一探究竟。

首要看到Text仅仅一个简略的静态组件StatelessWidget

Flutter中如何获取Text截断后的字符串

从build办法中能够看到回来的是一个RichText,并将maxLines参数进行传递。

Flutter中如何获取Text截断后的字符串

接着往下看RichText,能够看到RichText继承了MultiChildRenderObjectWidget多子烘托Widget,一定有创建烘托目标的当地。

Flutter中如何获取Text截断后的字符串

经过createRenderObject目标回来 RenderParagraph目标,并将maxLine参数持续传递

Flutter中如何获取Text截断后的字符串

点进去看一看,记住这个烘托目标

Flutter中如何获取Text截断后的字符串

经过结构办法将参数传递给自身保护的私有成员变量 TextPainter,这个目标是Flutter的文本制作器,经过它来处理文本的布局与制作,那持续点进去看一看。

Flutter中如何获取Text截断后的字符串

最终在布局和制作办法时会触发_createParagraphStyle办法,回来ParagraphStyle目标,这儿的触发机遇便是上面烘托目标布局制作时调用的,所以也能够了解TextPainter便是Flutter结构烘托文本处理的封装目标。

Flutter中如何获取Text截断后的字符串
Flutter中如何获取Text截断后的字符串

这个目标主要用来确认文本的阶段款式,而maxLines截取操作只会影响阶段的显现,并不会影响文本本身的款式,这儿判断了是否设置了文本TextStyle款式。如果没有设置运用默认的款式。 点进去看一看

Flutter中如何获取Text截断后的字符串

最终经过结构办法触发_encodeParagraphStyle办法,文本特点会直接经过和c++层交互进行保存,TextStyle和StrutStyle款式的设置原理也相同。最后经过烘托目标触发layout办法确认文本制作区域,也便是说设置maxLines之后文本内容不会改动,但文本的制作区域会产生改动。

解决方案

咱们现在知道maxLine本身是针对UI来进行切断的,并不会改动设置的内容特点,如果想要获取切断后的文本数据咱们该怎么操作呢, 其实TextPainter给咱们供给了一些Api办法,咱们能够直接运用。
经过didExceedMaxLines办法咱们能够判断出,该文本是否超过最大行设置。
经过getPositionForOffset能够回来一个TextPosition目标,里面的offset特点便是咱们需求的切断后字符串在原始文本傍边的index索引。

代码:

class TextUtil {
/// 获取最大行文字字数
static int calculateTextMaxTextPos(String value, double fontSize,
    {required double fontHeight, required double maxWidth, required EdgeInsetsGeometry padding, int maxLines = 3}) {
  final TextPainter painter = TextPainter(
      locale: WidgetsBinding.instance.window.locale,
      textDirection: TextDirection.ltr,
      maxLines: maxLines,
      strutStyle: StrutStyle(forceStrutHeight: true, fontSize: fontSize, height: fontHeight),
      text: TextSpan(
        text: value,
        style: TextStyle(
          height: fontHeight,
          fontSize: fontSize,
        ),
      ),
      textAlign: TextAlign.center);
  painter.layout(maxWidth: maxWidth - padding.horizontal);
  final didExceedMaxLines = painter.didExceedMaxLines;
  // print('是否超出最大行$didExceedMaxLines');
  if (didExceedMaxLines) {
  final position = painter.getPositionForOffset(Offset(
    painter.width,
    painter.height,
  ));
  return position.offset;
  }
  return 0;
}
}

运用场景

有了这个办法,咱们在一些产品需求为文字结尾添加打开收起的骚操作就十分的方便了,具体的封装就留给你们啦,并且经过这种方式还能够核算电子书每页数据,也是十分的快速,同时也优化了下之前模仿手势翻页电子书的核算。相较于之前核算文字高度核算量少了很多。
链接:booxfx 电子书模仿手势翻页。