【发布时间】:2021-06-22 12:25:38
【问题描述】:
信息
我需要将打字动画应用于我使用 Flutter 构建的网站上的文本。我已经成功实现了这个动画。对于要应用的动画,必须知道要写入屏幕并作为参数的文本的“长度”和“样式”属性的值。这是我写的小部件:
// @dart=2.9
import 'package:flutter/material.dart';
// ignore: must_be_immutable
class TypeWriterAnimatedText extends StatefulWidget {
TextSpan textSpan;
TypeWriterAnimatedText({Key key, @required this.textSpan}) : super(key: key);
@override
_TypeWriterAnimatedTextState createState() => _TypeWriterAnimatedTextState();
}
class _TypeWriterAnimatedTextState extends State<TypeWriterAnimatedText> with TickerProviderStateMixin {
Animation<double> _textBlinkCursorAnimation;
Animation<double> _textBlinkCursorAnimationCurve;
AnimationController _textBlinkCursorAnimationController;
bool _blink = true;
@override
void initState() {
super.initState();
_textBlinkCursorAnimationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 200));
_textBlinkCursorAnimationCurve = CurvedAnimation(
parent: _textBlinkCursorAnimationController,
curve: Curves.easeInOutQuart,
reverseCurve: Curves.linear);
_textBlinkCursorAnimation = Tween<double>(begin: 0, end: 1)
.animate(_textBlinkCursorAnimationCurve)
..addListener(() {
setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed && _blink == true) {
_textBlinkCursorAnimationController.reverse();
} else if (status == AnimationStatus.dismissed && _blink == true) {
_textBlinkCursorAnimationController.forward();
}
});
_textBlinkCursorAnimationController.forward();
}
@override
Widget build(BuildContext context) {
return Container(
height: 100,
child: TweenAnimationBuilder<int>(
tween: IntTween(begin: 0, end: widget.textSpan.text.length),
builder: (BuildContext context, int value, Widget child){
WidgetsBinding.instance.addPostFrameCallback((_){
if(value == widget.textSpan.text.length){
Future.delayed(Duration(milliseconds: 1800)).then((value){
setState(() {
_blink = false;
_textBlinkCursorAnimationController.reset();
});
});
}
});
return SelectableText.rich(
TextSpan(
children: [
widget.textSpan,
TextSpan(
text: _blink == false ? '' : '_',
style: widget.textSpan.style.copyWith(color: widget.textSpan.style.color.withOpacity(_textBlinkCursorAnimation.value)),
),
]),
);
},
duration: Duration(seconds: 2),
),
);
}
}
问题
但是我编写的应用动画的小部件需要在构造函数中将 TextSpan 作为参数。在这里,我遇到了一个问题。 TextSpan 处于嵌套结构中。另一方面,我需要在作为参数的 TextSpan 中找到所有“文本”属性的“长度”总和,以及最后一个 TextSpan 的“文本”属性的“样式”。但是由于 TextSpan 是嵌套的,因此其中一些对于“长度”和“样式”getter(widget.textSpan.text.length 和 widget.textSpan.style)返回 null。这导致我收到错误消息。
我想做什么?
即使我作为 TextSpan 提供给 Widget 的数据包含嵌套的 TextSpan,我也需要访问所有“文本”的“长度”属性并找到它的总和。例如,我需要找到'Text1-1','Text1-2'和'Text2'字符串的长度之和,即使有这样的数据:
TextSpan(
children: [
TextSpan(
children: [
TextSpan(
text: 'Text1-1',
style: TextStyle(
fontSize: 40,
fontFamily: 'RobotoMono-Bold',
color: Colors.white),
),
TextSpan(
text: 'Text1-2',
style: TextStyle(
fontSize: 16,
fontFamily: 'RobotoMono-Bold',
color: Colors.white),
),
],
style: TextStyle(
fontSize: 40,
fontFamily: 'RobotoMono-Bold',
color: Colors.white),
),
TextSpan(
text: 'Text2',
style: TextStyle(
fontSize: 16,
fontFamily: 'RobotoMono-Bold',
color: Colors.white),
),
],
),
【问题讨论】: