我复制了一个动画按钮的粘贴代码,该按钮调用setState,因为它向动画控制器添加了一个侦听器。
这篇文章和答案:
声明不建议在这种情况下调用setState,因为每次按下按钮时,它将重建整个UI。说得通!
现在,当我使用AnimatedBuilder时,它将停止工作。我究竟做错了什么?
编码:
class _AnimatedButtonState extends State<AnimatedButton>
with SingleTickerProviderStateMixin {
final style = GoogleFonts.volkhov(
color: Colors.black,
fontSize: 15,
);
double _scale;
AnimationController _controller;
@override
void initState() {
super.initState();
_controller = AnimationController(
vsync: this,
duration: Duration(milliseconds: 100),
lowerBound: 0.0,
upperBound: 0.1);
// _controller.addListener(() {
// setState(() {});
// });
}
@override
void dispose() {
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
_scale = 1 - _controller.value;
return GestureDetector(
onTap: _onTap,
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onTapCancel: _onTapCancel,
child: AnimatedBuilder( // HERE HERE
animation: _controller,
child: _animatedButtonUI,
builder: (context, child) {
return Transform.scale(
scale: _scale,
child: child,
);
},
)
);
}
_onTapUp(TapUpDetails details) => _controller.reverse();
_onTapDown(TapDownDetails details) => _controller.forward();
_onTapCancel() => _controller.reverse();
Widget get _animatedButtonUI => Container(
height: 100,
width: 250,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100),
gradient: LinearGradient(
begin: Alignment.bottomLeft,
end: Alignment.bottomRight,
colors: [Colors.green, Colors.green[400], Colors.green[500]],
),
),
child: Center(
child: Text(
'Save',
style: TextStyle(
fontSize: 25,
fontWeight: FontWeight.bold,
color: Colors.black,
),
),
),
);
旁注:之所以找到此提示,是因为我试图使按钮对单击/触摸的响应更加灵敏。使用setState时,在电话上快速单击和触摸不会触发动画。相反,它花费的时间比用户的随意触摸要长。如果您也能帮助我,我将非常感谢。
问题是,_scale
由于缺少,您正将其用作动画的值而未更新setState
。_scale
要更新的唯一地方是有状态窗口小部件的build方法。build
在第一次setState
调用when之后,仅再次调用一次,导致_scale
未按需要进行更新。
AnimatedBuilder
与调用基本上相同setState
,但是它会将重建仅隔离到builder
自身,而不是将有状态的窗口小部件作为一个整体进行隔离,因此这被认为在性能上更好。
为了解决这个问题,只需移动_scale = 1 - _controller.value;
到builder
的AnimatedBuilder
。
@override
Widget build(BuildContext context) {
//_scale = 1 - _controller.value; NOT HERE
return GestureDetector(
onTap: _onTap,
onTapDown: _onTapDown,
onTapUp: _onTapUp,
onTapCancel: _onTapCancel,
child: AnimatedBuilder(
animation: _controller,
child: _animatedButtonUI,
builder: (context, child) {
_scale = 1 - _controller.value; //HERE
return Transform.scale(
scale: _scale,
child: child,
);
},
)
);
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句