Flutter:简单搞一个内容高亮

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

如上的效果,在Flutter当中,实现起来可以说是无比的简单,毕竟原生的组件都给我们提供了,那就是富文本组件RichText。

针对今天的内容,简单的列一个大纲,主要内容如下:

1、案例简单效果

2、认识RichText

3、文本的高亮实现逻辑

4、高亮组件源码

一、案例简单效果

1、简单的内容高亮展示

2、列表形式内容展示

二、认识RichText

要实现高亮效果,那么我们必须了解富文本组件RichText,话又说回来,什么是富文本呢?简单来说,它是一种特殊的文本格式,比普通文本更加丰富多彩,可以包含各种字体、颜色、大小等元素,使文本更加生动、有趣,比如我们常见的阅读协议等场景,均可采用富文本形式,这是原生的文本无法实现的效果。

初识构造

构造属性需要注意的是,这里的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.parent

TextWidthBasis.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))
            ])

效果:

当然了,除了上述写法之外,也可以使用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,我们就需要动态的创建,然后动态的改变其样式。

这里的动态也是十分的简单,无非就是字符串的截取,分别是开头、结尾、和中间三种情况进行截取,如下图所示。

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

主要的逻辑如下:

 //搜索内容为空
    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很是简单,上边是搜索框,下面是展示的内容,这里就不贴了,高亮组件已经给大家提供了,大家可以直接复制使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/76355.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【BI看板】Docker-compose安装Superset,安装最新版本2.1.0

软件及环境准备 docker&#xff0c; docker-compose docker-compose安装 字节码安装 #wget https://github.com/docker/compose/releases/download/v2.5.0/docker-compose-linux-x86_64 #mv docker-compose-linux-x86_64 docker-compose #chmod x /usr/local/bin/docker-com…

【BASH】回顾与知识点梳理(二十九)

【BASH】回顾与知识点梳理 二十九 二十九. 进程和工作管理29.1 什么是进程 (process)进程与程序 (process & program)子进程与父进程&#xff1a;fork and exec&#xff1a;进程呼叫的流程系统或网络服务&#xff1a;常驻在内存的进程 29.2 Linux 的多人多任务环境多人环境…

echarts多条折线图

代码 <template><div><!-- 折线图 --><div id"average-score1" class"risk-percent" /></div> </template><script> import * as echarts from "echarts";export default {name: "StrategicRis…

模拟IIC——关于模拟IIC的IO口的配置选取推挽输出还是开漏输出,以及是否需要更改IO口输入输出模式和是否需要对IO配置上拉

问题如下 当时我以为引脚配错了&#xff0c;原理图明明是B引脚&#xff0c;为何程序是C呢 查了一下资料&#xff0c;顿悟了 https://blog.csdn.net/m0_62243928/article/details/125779308 在使用模拟IIC的时候&#xff0c;观看别人的程序的时候发现了程序之间的一些不一…

vscode vue3+vite 配置eslint

vue2webpackeslint配置 目前主流项目都在使用vue3vite&#xff0c;因此针对eslint的配置做了一下总结。 引入ESlint、pritter 安装插件&#xff0c;执行以下命令 // eslint // prettier // eslint-plugin-vue // eslint-config-prettier // eslint-plugin-prettier yarn ad…

【Linux操作系统】举例解释Linux系统编程中文件io常用的函数

在Linux系统编程中&#xff0c;文件IO操作是非常常见和重要的操作之一。通过文件IO操作&#xff0c;我们可以打开、读取、写入和关闭文件&#xff0c;对文件进行定位、复制、删除和重命名等操作。本篇博客将介绍一些常用的文件IO操作函数。 文章目录 1. open()1.1 原型、参数及…

【git clone error:no matching key exchange method found】

拉起项目代码报错 git clone ssh://uidxxxgerrit-xxxxxxxx Cloning into ‘xxxxx’… Unable to negotiate with xxx.xx.xxx.ip port xxxxx: no matching key exchange method found. Their offer: diffie-hellman-group14-sha1,diffie-hellman-group1-sha1 fatal: Could not …

JavaScript版本ES5/ES6及后续版本

JavaScript简史 1995&#xff1a; Brendan Eich在短短10天内创建了JavaScript的第一个版本。它被称为摩卡&#xff0c;但已经具备了现代JavaScript的许多基本特性! 1996&#xff1a; 为了吸引Java开发人员&#xff0c;Mocha先是更改为LiveScript&#xff0c;然后又更改为Ja…

R语言实现随机生存森林(2)

library(survival) library(randomForestSRC) help(package"randomForestSRC") #构建普通的随机生存森林 data(cancer,package"survival") lung$status<-lung$status-1 rfsrc.fit1 <- rfsrc(Surv(time, status) ~ ., lung,ntree 100,block.size 1,…

两只小企鹅(Python实现)

目录 1 和她浪漫的昨天 2 未来的旖旎风景 3 Python完整代码 1 和她浪漫的昨天 是的,春天需要你。经常会有一颗星等着你抬头去看&#xff1b; 和她一起吹晚风吗﹖在春天的柏油路夏日的桥头秋季的公园寒冬的阳台&#xff1b; 这世界不停开花&#xff0c;我想放进你心里一朵&am…

2023年国赛数学建模思路 - 复盘:人力资源安排的最优化模型

文章目录 0 赛题思路1 描述2 问题概括3 建模过程3.1 边界说明3.2 符号约定3.3 分析3.4 模型建立3.5 模型求解 4 模型评价与推广5 实现代码 建模资料 0 赛题思路 &#xff08;赛题出来以后第一时间在CSDN分享&#xff09; https://blog.csdn.net/dc_sinor?typeblog 1 描述 …

股票杠杆怎么玩_线上杠杆炒股是否可靠?

在投资领域&#xff0c;股票杠杆投资被视为一种较高风险的投资方式&#xff0c;它可以以较小的自有资金控制较大的资金进行交易。而线上杠杆炒股则是利用互联网提供的配资平台&#xff0c;通过借款进行杠杆交易。本文将从两个方面探析股票杠杆投资的玩法以及线上杠杆炒股的可靠…

配置/var/tmp/fstab 权限/配置用户账户/查找文件/查找字符串

目录 配置/var/tmp/fstab 权限 配置用户账户 查找文件 查找字符串 创建归档 配置/var/tmp/fstab 权限 配置文件权限&#xff0c;将文件 /etc/fstab 复制到 /var/tmp/fstab 。配置 /var/tmp/fstab 的权限以满足 如下条 件&#xff1a; /var/tmp/fstab 属于 root 用户…

Pycharm社区版连接WSL2中的Mysql8.*

当前时间2023.08.13&#xff0c;Windows11中默认的WSL版本已经是2了&#xff0c;在WSL2中默认的Ubuntu版本已经是22.04&#xff0c;而Ubuntu22.04中默认的Mysql版本已经是8.*。 Wsl 2 中安装mysql WSL2中安装Mysql的方法参考自微软官方文档【开始使用适用于 Linux 的 Windows …

.Net程序调试时接受外部命令行参数方式

1.对项目右键&#xff0c;属性 2.在调试中打开常规&#xff0c;打开调试启动配置文件UI 3.输入需要的命令行参数

Sencha Ext.NET Crack,构建Blazing快速应用

Sencha Ext.NET Crack,构建Blazing快速应用 Sencha Ext.NET是一个高级的ASP.NET核心组件框架&#xff0c;它包含了强大的跨浏览器Sencha Ext JS库。通过140多个预构建和专业测试的UI组件实现企业级性能和生产效率。Sencha Ext.NET使用尖端的Web技术创建功能强大的Web应用程序&a…

Docker自动化部署安装(十)之安装SonarQube

这里选择的是&#xff1a; sonarqube:9.1.0-community (推荐使用) postgres:9.6.23 数据库(sonarqube7.9及以后便不再支持mysql&#xff0c;版本太低的话里面的一些插件会下载不成功的) 1、docker-sonarqube.yml文件 version: 3 services:sonarqube:container_name: sonar…

Flink源码之JobMaster启动流程

Flink中Graph转换流程如下&#xff1a; Flink Job提交时各种类型Graph转换流程中&#xff0c;JobGraph是Client端形成StreamGraph后经过Operator Chain优化后形成的&#xff0c;然后提交给JobManager的Restserver&#xff0c;最终转发给JobManager的Dispatcher处理。 Completa…

在浏览器中使用javascript打印HTML中指定Div带背景图片内容生成PDF电子证书查询的解决方案

在浏览器中使用javascript打印HTML中指定Div带背景图片内容生成PDF电子证书查询的解决方案 一、指定内容打印二、背景图片打印1.CSS背景图片设置2.div相对定位居中 三、完整案例展示1.CSS样式表2.HTML容器构建 一、指定内容打印 要调用浏览器中的打印功能&#xff0c;并指定需…

机器学习笔记 - 基于PyTorch + 类似ResNet的单目标检测

一、获取并了解数据 我们将处理年龄相关性黄斑变性 (AMD) 患者的眼部图像。 数据集下载地址,从下面的地址中,找到iChallenge-AMD,然后下载。 Baidu Research Open-Access Dataset - DownloadDownload Baidu Research Open-Access Datasethttps://ai.baidu.com/bro…