【问题标题】:Cannot disable appearance animations on a "floatingActionButton" widget无法在“floatingActionButton”小部件上禁用外观动画
【发布时间】:2020-09-22 12:11:56
【问题描述】:

Scaffold 的 floatingActionButton 属性接受任何小部件,因此我在那里使用一排几个自定义容器来利用浮动效果。我已将 floatingActionButtonLocation 属性设置为“centerFloat”。问题是,每当我使用这样的小部件推送新页面时,它都会使用我想要禁用的奇怪动画。我发现了这个:Disable Scaffold FAB animation,所以我扩展了 FloatingActionButtonAnimator 并尝试了上述示例中显示的内容,但不幸的是,它没有帮助。我轻松地处理了偏移量。但旋转和缩放动画仍然存在。即使调整 Tween 对象的开始和结束值也无济于事。

这是脚手架中的设置:

    floatingActionButton: ActionControls(),
    floatingActionButtonLocation:
        FloatingActionButtonLocation.centerFloat,
    floatingActionButtonAnimator: NoScalingAnimation(),

这些是 ActionControl,基本上是我的浮动按钮:

class ActionControls extends StatelessWidget {
  Widget _iconButton({
    @required BuildContext context,
    @required IconData icon,
    @required Function function,
    Color color,
  }) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(5),
        color: color == null ? Theme.of(context).accentColor : color,
      ),
      child: IconButton(
        icon: Icon(
          icon,
          size: 30,
          color: Colors.white,
        ),
        onPressed: function,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        _iconButton(
          context: context,
          icon: Icons.keyboard_arrow_left,
          function: () {},
        ),
        const SizedBox(width: 10),
        _iconButton(
          context: context,
          icon: Icons.add,
          function: () {},
        ),
      ],
    );
  }
}

这是我的 FloatingActionButtonAnimator:

class NoScalingAnimation extends FloatingActionButtonAnimator {
  @override
  Offset getOffset({Offset begin, Offset end, double progress}) {
    return end;
  }

  @override
  Animation<double> getRotationAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }

  @override
  Animation<double> getScaleAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }
}

有问题的动画示例: https://imgur.com/a/1GQVUol

【问题讨论】:

  • 你能添加一些代码示例吗?
  • @Sebastian 完成。

标签: flutter animation floating-action-button scaffold


【解决方案1】:

FloatingActionButton 有一个参数 herotag,如果你没有定义它,它将使用 defaultHeroTag,当推送到新页面时它会检查同名的 herotags 并应用动画。

FloatingActionButton(
  heroTag: "MyFirstPage", //give it a custom name to avoid same heroTag in each page
  ...
 )

更新

class First extends StatelessWidget{

   @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            Text('First'),
            RaisedButton(
              onPressed: () {
                Navigator.push(
                  context,
                  MaterialPageRoute(
                    builder: (context) => Second(),
                  ),
                );
              },
              child: Text('Page'),
            ),
          ],
        ),
      ),
      floatingActionButton: ActionControls(),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButtonAnimator: NoScalingAnimation(),
    );
  }
}

class Second extends StatelessWidget{

  @override
  Widget build(BuildContext context){
    return Scaffold(
      appBar: AppBar(),
      body: Center(child: Text('My Second Page')),
      floatingActionButton: ActionControls(),
      floatingActionButtonLocation: FloatingActionButtonLocation.centerFloat,
      floatingActionButtonAnimator: NoScalingAnimation(),
      /*
      floatingActionButton: FloatingActionButton(
        child: const Icon(Icons.add),
        onPressed: () => print('tapped')
      ),
      */
    );
  }
}

class ActionControls extends StatelessWidget {
  Widget _iconButton({
    @required BuildContext context,
    @required IconData icon,
    @required Function function,
    Color color,
  }) {
    return Container(
      padding: const EdgeInsets.symmetric(horizontal: 10),
      decoration: BoxDecoration(
        borderRadius: BorderRadius.circular(5),
        color: color == null ? Theme.of(context).accentColor : color,
      ),
      child: IconButton(
        icon: Icon(
          icon,
          size: 30,
          color: Colors.white,
        ),
        onPressed: function,
      ),
    );
  }

  @override
  Widget build(BuildContext context) {
    return Row(
      mainAxisSize: MainAxisSize.min,
      children: <Widget>[
        _iconButton(
          context: context,
          icon: Icons.keyboard_arrow_left,
          function: () {},
        ),
        const SizedBox(width: 10),
        _iconButton(
          context: context,
          icon: Icons.add,
          function: () {},
        ),
      ],
    );
  }
}

class NoScalingAnimation extends FloatingActionButtonAnimator {
  @override
  Offset getOffset({Offset begin, Offset end, double progress}) {
    return end;
  }

  @override
  Animation<double> getRotationAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }

  @override
  Animation<double> getScaleAnimation({Animation<double> parent}) {
    return Tween<double>(begin: 1.0, end: 1.0).animate(parent);
  }
}

我制作了一个最小的可重现代码示例,但在第一页和第二页之间没有发现任何动画,甚至在第二页中将位置更改为 FloatingActionButtonLocation.endFloat 或实际插入了 FloatingActionButton()。我看到的唯一动画来自 MaterialPageRoute 从下面的动画淡入淡出

【讨论】:

  • 我没有使用实际的 FloatingActionButton,而是其他自定义小部件,因此没有 heroTag 字段。
  • 很奇怪,您的示例运行良好,但我的项目是相同的并且会导致问题。我将尝试再次调试。我还添加了动画的视频示例。无论如何,感谢您的帮助!
  • 好的,我开始从头开始重建页面,现在一切都很好。我会将这个问题视为已回答。
猜你喜欢
  • 2015-03-05
  • 2019-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 1970-01-01
  • 2011-01-29
相关资源
最近更新 更多