千家信息网

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

发表于:2025-11-21 作者:千家信息网编辑
千家信息网最后更新 2025年11月21日,这篇文章主要介绍"Flutter如何实现文本滚动高亮效果"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"Flutter如何实现文本滚动高亮效果"文章能帮助大家解
千家信息网最后更新 2025年11月21日Flutter如何实现文本滚动高亮效果

这篇文章主要介绍"Flutter如何实现文本滚动高亮效果"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"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 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 {  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如何实现文本滚动高亮效果"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

0