内容高亮并不陌生,特别是在查找内容页面,能够说四处可见,就拿这个应用而言,针对某一个关键字,咱们查找之后,与关键字相同的内容,则会高亮展现,如下图所示:

Flutter:简单搞一个内容高亮

如上的作用,在Flutter傍边,完成起来能够说是无比的简略,究竟原生的组件都给咱们供给了,那就是富文本组件RichText。

针对今日的内容,简略的列一个大纲,首要内容如下:

1、事例简略作用

2、认识RichText

3、文本的高亮完成逻辑

4、高亮组件源码


一、事例简略作用

1、简略的内容高亮展现

Flutter:简单搞一个内容高亮

2、列表形式内容展现

Flutter:简单搞一个内容高亮

二、认识RichText

要完成高亮作用,那么咱们必须了解富文本组件RichText,话又说回来,什么是富文本呢?简略来说,它是一种特殊的文本格式,比一般文本愈加丰富多彩,能够包含各种字体、色彩、巨细等元素,使文本愈加生动、风趣,比方咱们常见的阅览协议等场景,均可选用富文本形式,这是原生的文本无法完成的作用。

Flutter:简单搞一个内容高亮

初识结构

结构特点需要留意的是,这儿的text,和文本Text中的text是不一样的,文本Text指的是字符串,这儿的text指的是InlineSpan,当然了InlineSpan是笼统基类,一般咱们运用TextSpan。

RichText({
    super.key,
    required this.text,
    this.textAlign = TextAlign.start,
    this.textDirection,
    this.softWrap = true,
    this.overflow = TextOverflow.clip,
    this.textScaleFactor = 1.0,
    this.maxLines,
    this.locale,
    this.strutStyle,
    this.textWidthBasis = TextWidthBasis.parent,
    this.textHeightBehavior,
    this.selectionRegistrar,
    this.selectionColor,
  }) : assert(text != null),
       assert(textAlign != null),
       assert(softWrap != null),
       assert(overflow != null),
       assert(textScaleFactor != null),
       assert(maxLines == null || maxLines > 0),
       assert(textWidthBasis != null),
       assert(selectionRegistrar == null || selectionColor != null),
       super(children: _extractChildren(text));

常见结构特点概述:

const TextSpan({
    this.text,
    this.children,
    super.style,
    this.recognizer,
    MouseCursor? mouseCursor,
    this.onEnter,
    this.onExit,
    this.semanticsLabel,
    this.locale,
    this.spellOut,
  }) : mouseCursor = mouseCursor ??
         (recognizer == null ? MouseCursor.defer : SystemMouseCursors.click),
       assert(!(text == null && semanticsLabel != null));
特点 类型 概述
textAlign TextAlign 文本对齐方式TextAlign.left TextAlign.right TextAlign.cente TextAlign.justify TextAlign.start TextAlign.end
textDirection TextDirection 文本的方向TextDirection.ltr TextDirection.rtl
overflow TextOverflow 文字溢出的处理方式 TextOverflow.clip:剪切溢出的文本填满容器。 TextOverflow.fade:将溢出的文本淡化为透明。 TextOverflow.ellipsis:运用省略号表示文本已溢出。 TextOverflow.visible:出现容器外溢出的文本
maxLines int 最大行数
textWidthBasis TextWidthBasis 文本的宽度TextWidthBasis.parentTextWidthBasis.longestLine

TextSpan常见特点

特点 阐明
text String类型的文本
children 子组件
style TextStyle类型的文本款式能够设置文字的巨细、色彩、款式等
recognizer 指定手势交互 recognizer: TapGestureRecognizer()..onTap = () {},能够监听点击事情

简略事例:

RichText(
            text: const TextSpan(children: [
              TextSpan(text: "床前明月光,", style: TextStyle(color: Colors.black)),
              TextSpan(text: "疑是地上霜。", style: TextStyle(color: Colors.red)),
              TextSpan(text: "举头望明月,", style: TextStyle(color: Colors.blueAccent)),
              TextSpan(text: "低头思故乡。", style: TextStyle(color: Colors.tealAccent))
            ])

作用:

Flutter:简单搞一个内容高亮

当然了,除了上述写法之外,也能够运用Text.rich来完成,代码如下:

 const Text.rich(TextSpan(children: [
            TextSpan(text: "床前明月光,", style: TextStyle(color: Colors.black)),
            TextSpan(text: "疑是地上霜。", style: TextStyle(color: Colors.red)),
            TextSpan(text: "举头望明月,", style: TextStyle(color: Colors.blueAccent)),
            TextSpan(text: "低头思故乡。", style: TextStyle(color: Colors.tealAccent))
          ]))

三、文本的高亮完成逻辑

RichText能够完成一个富文本展现,那么如何运用这个组件完成某个内容高亮展现呢?首要,咱们要明白,高亮的内容是不固定的,一段内容的每个字符都有可能会高亮,所以针对TextSpan,咱们就需要动态的创建,然后动态的改动其款式。

这儿的动态也是十分的简略,无非就是字符串的截取,分别是最初、结束、和中心三种情况进行截取,如下图所示。

Flutter:简单搞一个内容高亮

当然了,需要留意,有可能要查找的这个内容,在整个内容中是多处存在的,这个时候,针对以上的逻辑,就需要遍历循环了,直至找到最终一个查找的内容。

Flutter:简单搞一个内容高亮

首要的逻辑如下:

 //查找内容为空
    if (_searchContent == "") {
      return Text(
        _content,
        style: _ordinaryStyle,
      );
    }
    List<TextSpan> richList = [];
    int start = 0;
    int end;
    //遍历,进行多处高亮
    while ((end = _content.indexOf(_searchContent, start)) != -1) {
      //如果查找内容在最初方位,直接高亮,此处不履行
      if (end != 0) {
        richList.add(TextSpan(
            text: _content.substring(start, end), style: _ordinaryStyle));
      }
      //高亮内容
      richList.add(TextSpan(text: _searchContent, style: _highlightStyle));
      //赋值索引
      start = end + _searchContent.length;
    }
    //查找内容只要在最初或许中心方位,才履行
    if (start != _content.length) {
      richList.add(TextSpan(
          text: _content.substring(start, _content.length),
          style: _ordinaryStyle));
    }
    return RichText(
      text: TextSpan(children: richList),
    );

四、高亮组件源码

源码很简略,能够结合列表组件或许独自运用,当然了,有一些特殊需求,文字加大或许改动布景等需求,都能够进行扩展。

class TextHighlight extends StatelessWidget {
  final TextStyle _ordinaryStyle; //一般的款式
  final TextStyle _highlightStyle; //高亮的款式
  final String _content; //文本内容
  final String _searchContent; //查找的内容
  const TextHighlight(this._content, this._searchContent, this._ordinaryStyle,
      this._highlightStyle,
      {super.key});
  @override
  Widget build(BuildContext context) {
    //查找内容为空
    if (_searchContent == "") {
      return Text(
        _content,
        style: _ordinaryStyle,
      );
    }
    List<TextSpan> richList = [];
    int start = 0;
    int end;
    //遍历,进行多处高亮
    while ((end = _content.indexOf(_searchContent, start)) != -1) {
      //如果查找内容在最初方位,直接高亮,此处不履行
      if (end != 0) {
        richList.add(TextSpan(
            text: _content.substring(start, end), style: _ordinaryStyle));
      }
      //高亮内容
      richList.add(TextSpan(text: _searchContent, style: _highlightStyle));
      //赋值索引
      start = end + _searchContent.length;
    }
    //查找内容只要在最初或许中心方位,才履行
    if (start != _content.length) {
      richList.add(TextSpan(
          text: _content.substring(start, _content.length),
          style: _ordinaryStyle));
    }
    return RichText(
      text: TextSpan(children: richList),
    );
  }
}

事例Demo很是简略,上边是查找框,下面是展现的内容,这儿就不贴了,高亮组件已经给我们供给了,我们能够直接仿制运用。