• Flutter 实现九宫格抽奖动画效果


    一、本文实现的九宫格抽奖动画效果如下

    二、主要分享下怎么一步一步来实现这个效果

    源代码地址

    1. 布局可以通过GridView轻松实现,只需在数据源的第五个位置插入一个元素用来标识是开始按钮
    2. 抽奖动画的实现,需要按顺时针循环选中奖品而且还需要从慢—>快—>慢的效果
    3. 抽奖按钮的缩放动画(这个比较简单)
    4. 最后动画停止在设定的奖品位置上

    三、实现抽奖UI布局

    1. 这里每个item 要区分是奖品还是开始按钮
    @override
    Widget build(BuildContext context) {
      return GridView.builder(
        itemCount: widget.list.length,
        padding: EdgeInsets.zero,
        gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
          crossAxisCount: 3,
          mainAxisSpacing: 18,
          crossAxisSpacing: 18,
          childAspectRatio: 1,
        ),
        physics: const NeverScrollableScrollPhysics(),
        itemBuilder: (_, index) {
          ///构建每个奖品 和 开始抽奖按钮
          return _buildItem(widget.list[index], index);
        },
      );
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    1. 最重要的动画实现,这里可以使用StepTween动画给定一个begin, end最终会返回[begin,end]区间内的整数序列,这样就可以依次选中每一个奖品
    void _initAnimation() {
      _controller = AnimationController(
        vsync: this,
        duration: const Duration(milliseconds: 5500),
      );
      _animation = StepTween(begin: 0, end: 8).animate(
        CurvedAnimation(parent: _controller, curve: Curves.ease),
      );
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1、最终在item上使用AnimationBuilder进行动画监听,就可以时时获取当前选中的奖品下标。
    2、上面说了需要实现从慢—>快—>慢的效果:只需要给动画设置个curve插值器即可,flutter已经为我们提供了许多种效果,具体查看Curves类即可。上面使用到的Curves.ease便是这种效果

    3、 关键问题怎么实现顺时针旋转呢?

    上面已经通过动画可以产生[0,8]内的整数了,所以只需要和那个8个奖品item对应即可,如下:

    旋转的顺序为:0—>1—>2—>5—>8—>7—>6—>3 所以通过如下转换即可实现

    int get _animationIndex {
      return [0, 1, 2, 5, 8, 7, 6, 3][_animation.value % 8];
    }
    
    • 1
    • 2
    • 3

    4、 最后一步,怎么让动画停在中间的奖品上?

    从上面分析可以轻松的知道给定[0,8]最终动画执行完会回到0第一个奖品处,所以如果想落在某一个上只需要知道奖品离第一个奖品需要几步。假设需要抽中iPad,则需要3步,所以只需要在初始动画给定end的时候加上这个数值即可

     void _initAnimation() {
       _controller = AnimationController(
         vsync: this,
         duration: const Duration(milliseconds: 5500),
       );
       _animation = StepTween(begin: 0, end: 8 + 3).animate(
         CurvedAnimation(parent: _controller, curve: Curves.ease),
       );
     }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    四、最后要实现旋转多圈的效果,相信你应该能想到只需要改变end的值即可。这里主要是记录下下具体的实现思路,大家可以结合源代码来查看
  • 相关阅读:
    转载-Blazor Debugging Improvements in Rider 2021.2
    新版本idea中使用springboot 国际化 Resource Bundle不显示
    这五个bug,论文绘图时千万别碰!
    使用蒙特卡罗模拟期权定价
    11、利用大津算法完成一张图片的前景分割
    Revit插件“土建模块”的生成圈梁功能使用
    [扩展欧几里得]Draw a triangle 2022年桂林站E
    R语言caTools包进行数据划分、scale函数进行数据缩放、e1071包的naiveBayes函数构建朴素贝叶斯模型
    YOLOv5如何训练自己的数据集
    对抗生成网络GAN系列——GANomaly原理及源码解析
  • 原文地址:https://blog.csdn.net/a_zhon/article/details/127425460