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 src) { return 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文本高亮内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
原文出处:https://juejin.cn/post/7075927270300319758
相关文章
python Matplotlib基础--如何添加文本和标注
这篇文章主要介绍了python Matplotlib基础--如何添加文本和标注,帮助大家更好的利用Matplotlib绘制图表,感兴趣的朋友可以了解下...2021-01-26- 这篇文章主要介绍了微信小程序 富文本转文本实例详解的相关资料,需要的朋友可以参考下...2016-10-25
- 猪先飞网之前分享过多篇关于帝国CMS当前栏目高亮的教程,点此查看 ,各有各的特点,各有各的优势,今天猪先飞网再分享一篇帝国CMS自定义导航栏目当前栏目高亮教程,于之前的不同处在...2015-12-30
- 本文通过一个简单的代码给大家介绍C# 输出字符串到文本文件中,代码简单易懂,非常不错,具有一定的参考借鉴价值,需要的朋友参考下吧...2020-06-25
代码块高亮可复制显示js插件highlight.js+clipboard.js整合
最近有个需求是将jsp页面上的某一段代码块格式化成类似CSDN的代码块的样式,而且很多平台都使用了这样的功能,下面就为大家简单分享一下...2021-02-17- 这篇文章主要介绍了python docx的超链接网址和链接文本操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-06
超漂亮的Bootstrap 富文本编辑器summernote
Summernote 是一个简单,灵活,所见即所得(WYSIWYG)的编辑器,基于 jQuery 和 Bootstrap 构建。对bootstrap 文本编辑器相关知识感兴趣的朋友一起学习吧...2016-04-06- Perl合并文本的一段实例代码,需要的朋友可以参考下...2020-06-29
Flutter悬浮按钮FloatingActionButton使用详解
本文主要介绍了Flutter悬浮按钮FloatingActionButton使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-07-12- 登录页面在 App 开发中非常常见,本篇借登录页面的开发介绍了文本框 TextField组件的使用,同时使用文本框的装饰属性实现了个性化文本框设置。...2021-06-05
Flutter 底部弹窗ModelBottomSheet的使用示例
在实际开发过程中,经常会用到底部弹窗来进行快捷操作,例如选择一个选项,选择下一步操作等等。在 Flutter 中提供了一个 showModelBottomSheet 方法用于弹出底部弹窗,本篇介绍如何使用底部弹窗。...2021-06-07- 发生场合:当左边对象是浮动的,右边对象采用外补丁的左边距来定位,则右边对象内的文本会离左边有3px的空白误差。 没加修正: 运行代码框 代码如下 复制代...2017-07-06
- 这篇文章主要为大家详细介绍了jQuery实现图片高亮显示,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2021-10-21
- 在实际开发过程中,往往开始是完成功能层面的开发,然而再考虑组件封装和代码优化。当然,组件封装越早做越好,因为这样会提高整个团队开发的规范性和效率。本文将介绍如何封装一个文本输入框组件...2021-06-05
- 这篇文章主要介绍了Flutter项目在 iOS14 启动崩溃的解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-09-24
- 这篇文章主要介绍了flutter实现点击事件,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-26
- PS如何让文字绕着圈显示呢?小编给大家带来了一篇简单的教程,教大家如何在PS软件中制作文字绕着圈显示,同学们快来看看吧 一提到ps就会想到图片处理,photoshop中有一个...2016-12-15
灵动标签完美实现当前栏目高亮-支持二级栏目及内容页及栏目排序
帝国CMS实现当前栏目高亮,官网论坛也有一些方法。但都各有缺陷,比如 不支持静态化的栏目页,或不支持内容页。再者就是调用出来的栏目无法自定义排序,也就是只能按栏目ID来排序...2015-12-30- 这篇文章主要介绍了在Vue 中获取下拉框的文本及选项值操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-13
- 本文我们来分享一个小工具 icdiff,他可以并列对比显示两个文件,不同的地方用高亮突出,非常好用。 发现一个刚出炉的文件比较小工具 icdiff. icdiff 可以并列显示两...2016-10-10