尝试避免在添加侦听器内进行setState调用时,AnimatedBuilder无法正常工作

国家

我复制了一个动画按钮的粘贴代码,该按钮调用setState,因为它向动画控制器添加了一个侦听器。

这篇文章和答案:

(文章)Flutter缓慢的动画:如何不设置状态

(如此回答)Flutter动画不起作用

声明不建议在这种情况下调用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;builderAnimatedBuilder

@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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

循环内的Firebase Realtime Database侦听器无法正常工作

OnClick以及侦听器无法正常工作

JavaScript全局错误侦听器无法正常工作

Html 类事件侦听器无法正常工作

邀请侦听器无法正常工作4.2

回调侦听器无法正常工作

Gmaps.map.callback无法正常工作,无法在Gmaps4rails中添加侦听器

Java Selenium和Appium无法正常工作无法启动REST http接口侦听器

从侦听器调用时如何更改 Unity 中的场景?

Xbee API-数据包侦听器似乎无法正常工作

LineChart侦听器无法正常工作,或者我错过了某些事情

动态创建搜索栏并为其提供侦听器,但它无法正常工作

没有submit()JSF,值更改侦听器无法正常工作

Google Maps侦听器无法在angular2 + typescript中正常工作

backref关系中的对称性无法与事件侦听器一起正常工作

事件侦听器无法正常工作,适用于 chrome,不适用于 Firefox

用于检测图像的“加载”事件侦听器已完成加载,无法在反应中正常工作

事件侦听器无法正常工作,如何解决问题?

关键侦听器由于某种原因无法正常工作

Android共享的偏好设置更改侦听器即使在全局引用侦听器的情况下也无法正常工作

尝试将事件侦听器添加到JTextField

布局中的searchview的关闭侦听器无法正常运行

JavaScript函数/事件侦听器无法正常运行

TabController侦听器多次调用。indexIsChanging如何工作?

通过addEventListener添加的事件侦听器被多次调用

没有静态引用,Android自定义视图事件侦听器将无法正常工作

JQuery.on()单击侦听器无法按预期工作

JavaScript mousemove事件侦听器无法按预期工作

UI 按钮侦听器 AddListener 无法循环工作