flutter - 调用 SetState() 后 SlideAnimation 不再启动
问题描述
我制作了一个简单的类,用于将小部件动画化到屏幕中:
class CustomSlideAnimation extends StatefulWidget {
static const String FROM_LEFT = 'FROM_LEFT';
static const String FROM_RIGHT = 'FROM_RIGHT';
final String from;
final Widget child;
const CustomSlideAnimation(
{Key key, this.from = FROM_LEFT, @required this.child})
: super(key: key);
@override
_CustomSlideAnimationState createState() => _CustomSlideAnimationState();
}
class _CustomSlideAnimationState extends State<CustomSlideAnimation>
with SingleTickerProviderStateMixin {
Animation<Offset> _offsetAnimation;
AnimationController _animationController;
@override
void initState() {
super.initState();
_animationController =
AnimationController(vsync: this, duration: Duration(milliseconds: 300));
_offsetAnimation = widget.from == CustomSlideAnimation.FROM_LEFT
? Tween<Offset>(
begin: Offset(-1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
curve: Curves.linear,
parent: _animationController,
))
: Tween<Offset>(
begin: Offset(1.0, 0.0),
end: Offset.zero,
).animate(CurvedAnimation(
curve: Curves.linear,
parent: _animationController,
));
_animationController.forward();
}
@override
void dispose() {
super.dispose();
_animationController.dispose();
}
@override
Widget build(BuildContext context) {
return SlideTransition(
position: _offsetAnimation,
child: widget.child,
);
}
}
还有一个简单的应用程序来演示这个问题:
void main() => runApp(Test());
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
bool widget1 = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: widget1
? CustomSlideAnimation(
child: InkWell(
child: Text('widget1'),
onTap: () {
setState(() {
widget1 = false;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
)
: CustomSlideAnimation(
child: InkWell(
child: Text('widget2'),
onTap: () {
setState(() {
widget1 = true;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
),
),
),
);
}
}
当我第一次启动应用程序时,Text小部件按预期滑入屏幕,但随后我点击它并调用 setState(),第二个Text小部件突然出现在屏幕上,并且没有发生幻灯片转换。
我打印了在所有类中调用 build 的时间,我看到 setState() 正在触发Test和CustomSlideTransition类中的构建,但没有触发CustomSlideTransition中的initState ()。
编辑以获得更多说明:即使将方法放入controller.forward()
该build()
方法也不起作用。
那么我错过了什么?
解决方案
你只需要给UniqueKey()
每个添加一个CustomSlideAnimation()
来告诉颤振把它们当作不同的小部件来对待。
void main() => runApp(Test());
class Test extends StatefulWidget {
@override
_TestState createState() => _TestState();
}
class _TestState extends State<Test> {
bool widget1 = true;
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: Center(
child: widget1
? CustomSlideAnimation(
key: UniqueKey(),
child: InkWell(
child: Text('widget1'),
onTap: () {
setState(() {
widget1 = false;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
)
: CustomSlideAnimation(
key: UniqueKey(),
child: InkWell(
child: Text('widget2'),
onTap: () {
setState(() {
widget1 = true;
});
},
),
from: CustomSlideAnimation.FROM_LEFT,
),
),
),
);
}
}
另外,保持controller.forward()
在里面initState()
推荐阅读
- javascript - SyntaxError: 意外的标记 ';' 在
在编译 ejs 时 - c++ - 我可以在 swift 中使用 c++ 静态库中定义的类类型吗
- angular - 从表/网格更新数据
- winforms - 如何将 Windows 窗体应用层保存为二维数组?
- c - C写入文件忽略新行?
- jakarta-ee - NoSuchMethodError - MtomStreamWriter.getAttachmentMarshaller()
- python - 如何在 Python 中更改 TFIDF 中的索引
- flutter - 如何将徽标放高一点并在其上方添加文字
- c# - 在 csharp 程序中调用的第一个构造函数
- python - Python 的 create_autospec 中的实例参数有什么作用?