Flutter實現(xiàn)文本滾動高亮效果的示例講解
前言
最近有個需求是人工語音播放時文本能隨語音朗讀時像歌詞滾動的效果.
原本第一考慮的時能隨時間字體漸變成更改后的顏色, 有比較流暢的走馬燈效果. 但最終實踐了幾次后發(fā)現(xiàn)要能夠逐字逐行漸變有一些麻煩, 不好實現(xiàn).
所以轉(zhuǎn)而變?yōu)閷⒆煮w直接將字體高亮, 一段文本區(qū)分成兩個部分, 一個部分是高亮文本, 也就是已朗讀的部分, 一個部分是剩下未朗讀的非高亮文本. 通過時時渲染頁面就能達成滾動高亮的效果.
功能實現(xiàn)
因為在Text中會存在兩段文本, 所以就不能單只用Text組件, 而改用Text.rich. 通過textSpan生成一個數(shù)組然后放到text.rich中. 所以本文需要處理, 而不是自己一個個拼接, 所以需要先有一個解析的類來負責處理.
需要在項目中加入第三方插件 string_scanner 用于掃描文本.
class StringParser {
// 導入的文本
final String content;
// 高亮部分尾部索引, 也就是兩段的區(qū)分位置
final int endIndex;
StringParser({required this.content, required this.endIndex});
late StringScanner _scanner;
// 解析函數(shù)
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++;
}
}
}之后需要定義一個高亮的數(shù)據(jù)類型, 用于方便修改之后想要高亮的文本樣式和默認樣式.
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);
}至此文本高亮和非高亮處理完成, 只需要在文件中導入后使用.
滾動效果則需要實現(xiàn)一個play函數(shù)里通過 Future.delayed來控制延時遞歸執(zhí)行.
_starPlay(flag) {
// flag用于判斷是 執(zhí)行還是暫停
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 =
"""一點不錯,”狐貍說?!皩ξ襾碚f,你還只是一個小男孩,就像其他千萬個小男孩一樣。我不需要你。你也同樣用不著我。對你來說,我也不過是一只狐貍,和其他千萬只狐貍一樣。但是,如果你馴服了我,我們就互相不可缺少了。對我來說,你就是世界上唯一的了;我對你來說,也是世界上唯一的了。""";
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);
});
}
}實現(xiàn)效果:

到此這篇關(guān)于Flutter實現(xiàn)文本滾動高亮效果的示例講解的文章就介紹到這了,更多相關(guān)Flutter文本高亮內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
android利用消息機制獲取網(wǎng)絡(luò)圖片
這篇文章主要為大家詳細介紹了android利用消息機制獲取網(wǎng)絡(luò)圖片的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-03-03
Android DataBinding單向數(shù)據(jù)綁定深入探究
看了谷歌官方文章確實寫的太簡略了,甚至看完之后有很多地方還不知道怎么回事兒或者怎么用,那么接下來我將通過文章全面介紹一下DataBinding單向數(shù)據(jù)綁定2022-11-11
AndroidStudio 使用過程中出現(xiàn)的異常(Gradle sync failed)處理辦法
本文主要介紹AndroidStudio 使用過程中出現(xiàn)的異常的解決辦法,這里幫大家舉例說明,如何處理出現(xiàn)這種問題,有需要的小伙伴可以參考下2016-09-09
Android自定義View實現(xiàn)左右滑動選擇出生年份
這篇文章主要介紹了Android自定義View實現(xiàn)左右滑動選擇出生年份,具有一定的參考價值,感興趣的小伙伴們可以參考一下2016-06-06
Assert.assertEquals()方法參數(shù)詳解
本文詳細講解了Assert.assertEquals()方法參數(shù),文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-12-12
Android實現(xiàn)讀取掃碼槍內(nèi)容(條形碼)
這篇文章主要為大家詳細介紹了Android實現(xiàn)讀取掃碼槍內(nèi)容、條形碼,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-09-09

