前言
今天逛掘金,突然看到一个打字机相关功能的一篇文章,想着自己也实现下,功能很简单,话不多说,看正文。
功能分析
打字机的功能效果有哪些
- 最终文本
- 当前文本
- 闪烁光标
最后我们根据自己的实际需求定义秒数展示即可。
功能实现
最终文本、当前文本用两个变量进行处理,我们下文围绕着光标处理讲述
光标功能
光标功能闪烁:我们可以用动画配合透明度进行实现(毫秒数根据自己喜好调整)
动画相关实现
AnimationController? controller;
Animation<double>? animationValue;
@override
void initState() {
controller = AnimationController(vsync: this,duration: Duration(milliseconds: 300));
animationValue = Tween<double>(begin: 0,end: 1).animate(controller!);
controller!.addListener(() {
if(controller!.isCompleted){
controller!.reset();
}
});
animationTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
if(currentText.length >= text.length){
timer.cancel();
return;
}
controller!.forward();
});
controller!.forward();
// controller!.repeat();
// TODO: implement initState
super.initState();
}
@override
void dispose() {
controller!.dispose();
// TODO: implement dispose
super.dispose();
}
动画实现后,我们在视图中添加文本标识即可
AnimatedBuilder(
animation: controller!,
builder: (context,widget){
return Opacity(
opacity: animationValue!.value,
child: Container(
child: Text(
"|",
style: TextStyle(
color: Colors.black,
fontSize: 25
),
),
),
);
}),
文本展示
我们前面提到,我们做打字机需要一个最终文本以及当前展示的文本,我们需要配合定时器并且追加每个新的字符串至展示文本中
定义文本追加方法
int count = 0;
/*
* @author Marinda
* @date 2024/7/15 16:19
* @description 修改文本方法
*/
changeText(){
String targetText = text.substring(count,count+1);
setState(() {
currentText += targetText;
count++;
});
print("当前添加文本为:${targetText}");
controller!.forward();
}
之后在我们的initState方法中定义计时器进行更新
textTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
if(currentText.length >= text.length){
timer.cancel();
return;
}
changeText();
});
之后我们在视图中追加显示文本控件即可
Container(
child: Text(
"$currentText",
style: TextStyle(
color: Colors.black,
fontSize: 24
),
),
),
最终代码
import 'dart:async';
import 'package:flutter/material.dart';
class Example01 extends StatefulWidget{
@override
State<StatefulWidget> createState() {
return Example01State();
}
}
class Example01State extends State<Example01> with TickerProviderStateMixin{
String text = "Hello World This a text ...";
String currentText = "";
bool showLoadingFlag = false;
int count = 0;
Timer? textTimer;
Timer? animationTimer;
AnimationController? controller;
Animation<double>? animationValue;
@override
void initState() {
controller = AnimationController(vsync: this,duration: Duration(milliseconds: 300));
animationValue = Tween<double>(begin: 0,end: 1).animate(controller!);
textTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
if(currentText.length >= text.length){
timer.cancel();
return;
}
changeText();
});
controller!.addListener(() {
if(controller!.isCompleted){
controller!.reset();
}
});
animationTimer = Timer.periodic(Duration(milliseconds: 500), (timer) {
if(currentText.length >= text.length){
timer.cancel();
return;
}
controller!.forward();
});
controller!.forward();
// controller!.repeat();
// TODO: implement initState
super.initState();
}
@override
void dispose() {
controller!.dispose();
// TODO: implement dispose
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
child:Row(
children: [
Container(
child: Text(
"$currentText",
style: TextStyle(
color: Colors.black,
fontSize: 24
),
),
),
AnimatedBuilder(
animation: controller!,
builder: (context,widget){
return Opacity(
opacity: animationValue!.value,
child: Container(
child: Text(
"|",
style: TextStyle(
color: Colors.black,
fontSize: 25
),
),
),
);
}),
],
),
)
);
}
/*
* @author Marinda
* @date 2024/7/15 16:19
* @description 修改文本方法
*/
changeText(){
String targetText = text.substring(count,count+1);
setState(() {
currentText += targetText;
count++;
});
print("当前添加文本为:${targetText}");
controller!.forward();
}
}
效果
结束语
感谢你的观看。