flutter - 从外部小部件触发小部件动画
问题描述
我有一个具有正常/动画状态的自定义小部件。有时我希望它是动画的,有时是静态的。
我做了一个简单的测试项目来演示我的问题:测试页面包含我的自定义小部件 ( ScoreBoard
) 和 2 个按钮来开始/停止动画记分板。我的问题是,记分板没有动画,即使我开始动画。
这是我的代码:
TestPage
:
class TestPage extends StatefulWidget {
@override
_TestPageState createState() => _TestPageState();
}
class _TestPageState extends State<TestPage> {
bool _animate;
@override
void initState() {
_animate = false;
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
ScoreBoard(
text: "Hello, world!",
animate: _animate,
),
FlatButton(
child: Text("START animation"),
onPressed: () {
setState(() {
_animate = true;
});
},
),
FlatButton(
child: Text("STOP animation"),
onPressed: () {
setState(() {
_animate = false;
});
},
),
],
),
);
}
}
记分板小部件:
class ScoreBoard extends StatefulWidget {
final String text;
final bool animate;
const ScoreBoard({Key key, this.text, this.animate}) : super(key: key);
@override
_ScoreBoardState createState() => _ScoreBoardState();
}
class _ScoreBoardState extends State<ScoreBoard>
with SingleTickerProviderStateMixin {
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(seconds: 1),
vsync: this,
)..forward();
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return widget.animate
? ScaleTransition(
child:
Text(widget.text, style: Theme.of(context).textTheme.display1),
scale: new CurvedAnimation(
parent: _controller,
curve: Curves.easeIn,
),
)
: Container(
child:
Text(widget.text, style: Theme.of(context).textTheme.display1),
);
}
}
你会这么好心来帮助我吗?提前致谢!
解决方案
回答
如果您初始化一个AnimationController
小部件并且没有为lowerBound
and指定参数upperBound
(这里就是这种情况),那么您的动画将默认以lowerBound
0.0 开始。
AnimationController({double value, Duration duration, String debugLabel, double lowerBound: 0.0, double upperBound: 1.0, AnimationBehavior animationBehavior: AnimationBehavior.normal, @required TickerProvider vsync }) 创建一个动画控制器。[...]
https://docs.flutter.io/flutter/animation/AnimationController-class.html
如果您初始化小部件的状态ScoreBoard
,则该方法forward
在您的应用程序的整个生命周期中仅被调用一次。该方法forward
使您的动画在 1 秒内从lowerBound
(0.0) 增加到(1.0)。upperBound
开始向前运行此动画(接近尾声)。
https://docs.flutter.io/flutter/animation/AnimationController/forward.html
forward
在我们的例子中,一旦方法被调用,就没有回头路了。我们只能停止动画。
按 Ctrl + F5 完全重启应用程序以查看动画。为了更清楚,将动画的持续时间更改为 10 秒。
顺便提一句。从 Dart 2 开始,您不需要使用new
关键字。
@override
void initState() {
super.initState();
_controller = AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
)..forward();
}
例子
要查看会发生什么,您可以将其添加到您的build
方法中:
@override
Widget build(BuildContext context) {
// Execute 'reverse' if the animation is completed
if (_controller.isCompleted)
_controller.reverse();
else if (_controller.isDismissed)
_controller.forward();
// ...
...并且不要在方法forward
中调用该initState
方法:
@override
void initState() {
super.initState();
_controller = new AnimationController(
duration: const Duration(seconds: 10),
vsync: this,
);
}
推荐阅读
- php - 重新索引树数组php的元素
- ios - 如何在 tableview 上加载 JSON?
- html - 我想将我的 UL 居中,但它不起作用
- c++ - 在 VC++ 2005 中将 crlf 添加到 WCHAR *
- c# - 只读依赖属性更新但在首次使用时不起作用
- c# - 无条件遍历 XML
- javascript - 错误:捆绑失败:错误:无法解析模块“react-native-vector-icons/Feather”
- c# - 从用户输入生成电子邮件正文,从控制器发送电子邮件?
- c - C - 接受指针作为参数的递归函数问题
- python - OpenCV GrabCut 在 GC_INIT_WITH_MASK 模式下不更新掩码