在颤动中旋转图标 180 度动画

Posted

技术标签:

【中文标题】在颤动中旋转图标 180 度动画【英文标题】:Rotate icon 180 degree with animation in flutter 【发布时间】:2021-09-11 11:26:00 【问题描述】:

我有一个IconButton,通常,它的图标是Icons.expand_more,但是当我按下它时,它的图标应该是Icons.expand_less。我想对此进行动画处理,以便如果我按下该按钮,它将旋转并从 upwords 指向 downwords。同样,当我按下expand_less 时,它应该变成expand_more 并带有旋转动画。我怎样才能做到这一点? 以下是我的代码:

    IconButton(
      icon:  _expanded ? Icon(Icons.expand_less) : Icon(Icons.expand_more),
      onPressed: () 
        setState(() 
           _expanded = !_expanded;
        );
      ,
   )

我尝试使用 animatedContainer 但它不起作用,因为我使用了两个不同的图标,并且我无法实现旋转效果。 我也尝试使用以下方法旋转图标,但是当它从 0 度旋转到 180 度时无法显示动画。

IconButton(
              icon: AnimatedContainer(
                  duration: Duration(seconds: 3),
                  child: Transform.rotate(
                      angle: _expanded ? 0 : 180 * math.pi / 180,
                      child: Icon(Icons.expand_less))),
              // icon:
              //     _expanded ? Icon(Icons.expand_less) : Icon(Icons.expand_more),
              onPressed: () 
                setState(() 
                  _expanded = !_expanded;
                );
              ,
            )

这是展开前的:

这是扩展后的:

我想要按钮点击时的旋转动画。

【问题讨论】:

感谢大家的回答!我发布了完整的解决方案below。 【参考方案1】:

感谢@krumpli。

    定义AnimationController _controller

    定义init方法为:

  @override
  void initState() 
    super.initState();

    _controller = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: 300),
      upperBound: 0.5,
    );
  
    定义dispose方法为:
@override
  void dispose() 
    super.dispose();
    _controller.dispose();
  
    使用小部件RotationTransition
RotationTransition(
              turns: Tween(begin: 0.0, end: 1.0).animate(_controller),
              child: IconButton(
                icon: Icon(Icons.expand_less),
                onPressed: () 
                  setState(() 
                    if (_expanded) 
                      _controller..reverse(from: 0.5);
                     else 
                      _controller..forward(from: 0.0);
                    
                    _expanded = !_expanded;
                  );
                ,
              ),
            )

别忘了在类定义中添加with SingleTickerProviderStateMixin

【讨论】:

【参考方案2】:

试试这个: 添加动画控制器:AnimationController _animationController:

initState() 
    _animationController = new AnimationController(
        vsync: this, duration: Duration(milliseconds: 300));
    

将您的图标包装在此:

RotationTransition(
         turns: Tween(begin: 0.0, end: 1.0)
                .animate(_animationController),
         child: IconButton(icon: //YOUR ICON),
         onPressed: () 
             setState(() 
        _animationController1.forward(from: 0.0);
      );
     ,
   ),
 )

最后:

  @override
  void dispose() 
    super.dispose();
    _animationController?.dispose();
  

【讨论】:

谢谢老兄!您的解决方案完成了旋转动画的工作,但我需要在展开和折叠时使用特定的旋转动画,不过我从您的解决方案中发现了这一点。 是的,使用标志进行简单修复。乐于助人!【参考方案3】:

看看这个test sample我为你准备的东西。

这也应用了一条曲线,这是一个很好的 Flutter 建议。

import 'package:flutter/material.dart';

class RotateIcon extends StatefulWidget 
  const RotateIcon(Key? key) : super(key: key);

  @override
  _RotateIconState createState() => _RotateIconState();


class _RotateIconState extends State<RotateIcon>
    with SingleTickerProviderStateMixin 
  late final AnimationController _controller;
  late final Animation<double> _animation;

  @override
  void initState() 
    super.initState();
    _controller = AnimationController(
        duration: const Duration(milliseconds: 500), vsync: this);
    _animation =
        Tween(begin: 0.0, end: .5).animate(CurvedAnimation(
        parent: _controller, curve: Curves.easeOut));
    

  @override
  void dispose() 
    super.dispose();
    _controller.dispose();
  

  @override
  Widget build(BuildContext context) 
    return Scaffold(
      body: SafeArea(
          child: Column(
            children: [
              RotationTransition(
                turns: _animation,
                child: const Icon(Icons.expand_more),
              ),
              ElevatedButton(
                  onPressed: () 
                    if (_controller.isDismissed) 
                      _controller.forward();
                     else 
                      _controller.reverse();
                    
                  ,
                  child: const Text("Animate"))
            ],
          )),
    );
  


【讨论】:

非常感谢!这正是我想要的:) 好的,我很高兴我的回答足够好。您现在可以使用您的代码自定义它并更改动画的时间 我从@krumpli 的回答中找到了解决方案,但是在看了你的解决方案之后(?)我确认了! 虽然此链接可能会回答问题,但最好在此处包含答案的基本部分并提供链接以供参考。如果链接页面发生更改,仅链接答案可能会失效。 - From Review 好的,我已经更新了答案,添加了整个类的重要代码。这样更好吗?

以上是关于在颤动中旋转图标 180 度动画的主要内容,如果未能解决你的问题,请参考以下文章

Android:围绕Y的第二次180度旋转镜像会反映图像

Android动画--Activity界面180度翻转

CSS3 从 0 旋转到 90,然后从 90 旋转到 180

CSS 动画中断变换

如何制作 OpenGL (GLUT) 旋转动画?

CSS关键帧动画中的平滑旋转