我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Flutter实现文本滚动高亮效果的示例讲解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Flutter实现文本滚动高亮效果的示例讲解

前言

最近有个需求是人工语音播放时文本能随语音朗读时像歌词滚动的效果.

原本第一考虑的时能随时间字体渐变成更改后的颜色, 有比较流畅的走马灯效果. 但最终实践了几次后发现要能够逐字逐行渐变有一些麻烦, 不好实现.

所以转而变为将字体直接将字体高亮, 一段文本区分成两个部分, 一个部分是高亮文本, 也就是已朗读的部分, 一个部分是剩下未朗读的非高亮文本. 通过时时渲染页面就能达成滚动高亮的效果.

功能实现

因为在Text中会存在两段文本, 所以就不能单只用Text组件, 而改用Text.rich. 通过textSpan生成一个数组然后放到text.rich中. 所以本文需要处理, 而不是自己一个个拼接, 所以需要先有一个解析的类来负责处理.

需要在项目中加入第三方插件 string_scanner 用于扫描文本.

class StringParser {
  // 导入的文本
  final String content;
  // 高亮部分尾部索引, 也就是两段的区分位置
  final int endIndex;

  StringParser({required this.content, required this.endIndex});

  late StringScanner _scanner;

  // 解析函数
  InlineSpan parser() {
    _scanner = StringScanner(content);

    parseContent();

    final List<InlineSpan> spans = [];

    int currentPosition = 0;

    // 需要高亮的部分
    spans.add(TextSpan(style: _spans.style, text: _spans.text(content)));
    currentPosition = _spans.end;

    // 未高亮的部分
    if (currentPosition != content.length) {
      spans.add(
          TextSpan(text: content.substring(currentPosition, content.length)));
    }

    return TextSpan(style: TextStyleSupport.defaultStyle, children: spans);
  }

  late SpanBean _spans;

  // 解析需要变成高亮的字符
  void parseContent() {
    int startIndex = 0;

    _spans = SpanBean(startIndex, endIndex);

    if (!_scanner.isDone) {
      _scanner.position++;
    }
  }
}

之后需要定义一个高亮的数据类型, 用于方便修改之后想要高亮的文本样式和默认样式.

class SpanBean {
  SpanBean(this.start, this.end);

  final int start;
  final int end;

  String text(String class="lazy" data-src) {
    return class="lazy" data-src.substring(start, end);
  }

  TextStyle get style => TextStyleSupport.highLightStyle;
}

class TextStyleSupport {
  static const defaultStyle = TextStyle(color: Colors.black, fontSize: 36);
  static const highLightStyle = TextStyle(color: Colors.green, fontSize: 36);
}

至此文本高亮和非高亮处理完成, 只需要在文件中导入后使用.

滚动效果则需要实现一个play函数里通过 Future.delayed来控制延时递归执行.

_starPlay(flag) {
	// flag用于判断是 执行还是暂停
    if (this.endIndex == content.length + 1 || !flag) {
      return;
    }

    parser = StringParser(content: content, endIndex: this.endIndex++);
    span = parser.parser();

    setState(() {});
    Future.delayed(Duration(milliseconds: 100)).then((value) {
      _starPlay(this.flag);
    });
  }

最终在文件里的代码则是

import 'package:flutter/material.dart';
import 'string_parser.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key? key}) : super(key: key);
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  late InlineSpan span;

  final String content =
      """一点不错,”狐狸说。“对我来说,你还只是一个小男孩,就像其他千万个小男孩一样。我不需要你。你也同样用不着我。对你来说,我也不过是一只狐狸,和其他千万只狐狸一样。但是,如果你驯服了我,我们就互相不可缺少了。对我来说,你就是世界上唯一的了;我对你来说,也是世界上唯一的了。""";

  late StringParser parser;
  int endIndex = 0;
  bool flag = true;

  @override
  void initState() {
    super.initState();
    parser = StringParser(content: content, endIndex: endIndex);
    span = parser.parser();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("滚动高亮文本"),
          actions: [
            ElevatedButton(
                onPressed: () {
                  this.flag = true;
                  _starPlay(flag);
                  print('开始');
                },
                child: Text("开始")),
            ElevatedButton(
                onPressed: () {
                  this.flag = false;
                  // _starPlay(flag);
                  print('暂停');
                },
                child: Text("暂停"))
          ],
        ),
        body: Padding(
          padding: const EdgeInsets.all(20.0),
          child: Text.rich(span),
        ));
  }

  _starPlay(flag) {
    if (this.endIndex == content.length + 1 || !flag) {
      return;
    }

    parser = StringParser(content: content, endIndex: this.endIndex++);
    span = parser.parser();

    setState(() {});
    Future.delayed(Duration(milliseconds: 100)).then((value) {
      _starPlay(this.flag);
    });
  }
}

实现效果:

到此这篇关于Flutter实现文本滚动高亮效果的示例讲解的文章就介绍到这了,更多相关Flutter文本高亮内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Flutter实现文本滚动高亮效果的示例讲解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

Flutter如何实现文本滚动高亮效果

这篇文章主要介绍“Flutter如何实现文本滚动高亮效果”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Flutter如何实现文本滚动高亮效果”文章能帮助大家解决问题。功能实现因为在Text中会存在两
2023-06-29

Unity实现卡片循环滚动效果的示例详解

这篇文章主要为大家详细介绍了如何利用Unity实现卡片循环滚动的效果,文中的实现步骤讲解详细,具有一定的借鉴价值,需要的可以参考一下
2022-12-09

如何使用CSS制作无缝滚动的文字展示效果的实现步骤

在网页设计中,无缝滚动的文字展示效果给人们带来了更加流畅和吸引人的用户体验。这种效果通常用于轮播图、滚动新闻等场景。本文将介绍一种使用CSS实现无缝滚动的文字展示效果的具体步骤,并提供相关的代码示例。步骤一:创建HTML结构首先,我们需要创
2023-10-21

Android应用-Flutter实现Android拖动到垃圾桶删除效果-Draggable和DragTarget的详细讲解

文章目录 Draggable介绍构造函数参数说明使用示例 DragTarget 介绍构造函数参数说明使用示例 DragTarget 如何接收Draggable传递过来的数据? Draggable介绍 Draggable
Android应用-Flutter实现Android拖动到垃圾桶删除效果-Draggable和DragTarget的详细讲解
2023-12-22

编程热搜

  • Android:VolumeShaper
    VolumeShaper(支持版本改一下,minsdkversion:26,android8.0(api26)进一步学习对声音的编辑,可以让音频的声音有变化的播放 VolumeShaper.Configuration的三个参数 durati
    Android:VolumeShaper
  • Android崩溃异常捕获方法
    开发中最让人头疼的是应用突然爆炸,然后跳回到桌面。而且我们常常不知道这种状况会何时出现,在应用调试阶段还好,还可以通过调试工具的日志查看错误出现在哪里。但平时使用的时候给你闹崩溃,那你就欲哭无泪了。 那么今天主要讲一下如何去捕捉系统出现的U
    Android崩溃异常捕获方法
  • android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
    系统的设置–>电池–>使用情况中,统计的能耗的使用情况也是以power_profile.xml的value作为基础参数的1、我的手机中power_profile.xml的内容: HTC t328w代码如下:
    android开发教程之获取power_profile.xml文件的方法(android运行时能耗值)
  • Android SQLite数据库基本操作方法
    程序的最主要的功能在于对数据进行操作,通过对数据进行操作来实现某个功能。而数据库就是很重要的一个方面的,Android中内置了小巧轻便,功能却很强的一个数据库–SQLite数据库。那么就来看一下在Android程序中怎么去操作SQLite数
    Android SQLite数据库基本操作方法
  • ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
    工作的时候为了方便直接打开编辑文件,一些常用的软件或者文件我们会放在桌面,但是在ubuntu20.04下直接直接拖拽文件到桌面根本没有效果,在进入桌面后发现软件列表中的软件只能收藏到面板,无法复制到桌面使用,不知道为什么会这样,似乎并不是很
    ubuntu21.04怎么创建桌面快捷图标?ubuntu软件放到桌面的技巧
  • android获取当前手机号示例程序
    代码如下: public String getLocalNumber() { TelephonyManager tManager =
    android获取当前手机号示例程序
  • Android音视频开发(三)TextureView
    简介 TextureView与SurfaceView类似,可用于显示视频或OpenGL场景。 与SurfaceView的区别 SurfaceView不能使用变换和缩放等操作,不能叠加(Overlay)两个SurfaceView。 Textu
    Android音视频开发(三)TextureView
  • android获取屏幕高度和宽度的实现方法
    本文实例讲述了android获取屏幕高度和宽度的实现方法。分享给大家供大家参考。具体分析如下: 我们需要获取Android手机或Pad的屏幕的物理尺寸,以便于界面的设计或是其他功能的实现。下面就介绍讲一讲如何获取屏幕的物理尺寸 下面的代码即
    android获取屏幕高度和宽度的实现方法
  • Android自定义popupwindow实例代码
    先来看看效果图:一、布局
  • Android第一次实验
    一、实验原理 1.1实验目标 编程实现用户名与密码的存储与调用。 1.2实验要求 设计用户登录界面、登录成功界面、用户注册界面,用户注册时,将其用户名、密码保存到SharedPreference中,登录时输入用户名、密码,读取SharedP
    Android第一次实验

目录