Flutter实战动画开发:翻页效果实现

2019-09-0522:11:14APP与小程序开发Comments8,697 views字数 2470阅读模式

学习Flutter动画时接触了Transform类,查找官方文档时无意间看到了时钟翻页动画觉得也挺好玩的,所以就想知道自己动手使用动画和Transform来实现翻页特效。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html

Flutter实战动画开发:翻页效果实现

思路

开始前自己也思考过如果实现翻页动画,但实际操作时却发现思路不太正确最后只好作罢。还是参考了已有翻页实现方式才知道其实方法很简单,通过Transform对数字上部分进行矩阵变化操作实现页面翻转效果。下面通过图片绘制更好的解释实现过程。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html

图解

下图所展示内容是从横切面看到的效果图。正常情况下是从示例图左边到右边的查看视角?。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html

Flutter实战动画开发:翻页效果实现
Flutter实战动画开发:翻页效果实现Flutter实战动画开发:翻页效果实现
Flutter实战动画开发:翻页效果实现Flutter实战动画开发:翻页效果实现
Flutter实战动画开发:翻页效果实现Flutter实战动画开发:翻页效果实现
  • STEP1
    首先可以使用ClipRect组件将数字分割成两部分。A、D分别代表用ClipRect分割数字上部分和数字下部分,并且用A和D来显示翻页的下一个数字。C和B则显示当前准备翻转的数字。开始时我们看到就是C和B组成的数字。
  • STEP2
    然后C使用Transform对C进行变形处理达到向上翻转动画效果:setEntry进行变形处理,rotateX向X轴做旋转操作,翻转角度为90度。
  • STEP3
    接着当C旋转90度的过程中底部A数字上部分就慢慢呈现出来。当C旋转到90度之后,开始是垂直不可见的D也进行90度向X轴旋转操作。这个过程中上个数字的下部分B就慢慢被遮盖。
  • STEP4
    最后D旋转了90度后,当前整个动画周期结束当前数字显示就是下一个值了。最终同时将A、B、C、D分别更改为下次需要显示的数值并将C、D重置回原来的位置进行下一轮动画。

代码部分

  • 数字分割部分
ClipRect(
      child: Align(
        alignment: _alignment,
        heightFactor: 0.5,
        child: Container(
          alignment: Alignment.center,
          width: 100,
          decoration: BoxDecoration(
            color: Colors.black,
            borderRadius: BorderRadius.all(Radius.circular(4.0)),
          ),
          child: Text(
            "$_value",
            style: TextStyle(
              fontSize: 80,
              color: Colors.white,
              fontWeight: FontWeight.w700,
            ),
          ),
        ),
      ),
    )
复制代码
  • 数字整体
 Column(
      mainAxisSize: MainAxisSize.min,
      children: [
        Stack(
          children: <Widget>[
            //下一个数字的上部分
            ClipRectText(_stateNum + 1, Alignment.topCenter),
            //当前数字的上部分,当_isReversePhase为true时和平面呈90度角相当于隐藏
            Transform(
                transform: Matrix4.identity()
                  ..setEntry(3, 2, 0.006)
                  ..rotateX(_isReversePhase ? pi / 2 : _animation.value),
                alignment: Alignment.bottomCenter,
                child: ClipRectText(_stateNum, Alignment.topCenter)),
          ],
        ),
        Padding(
          padding: EdgeInsets.only(top: 2.0),
        ),
        Stack(
          children: <Widget>[
            //当前数字的下部分
            ClipRectText(_stateNum, Alignment.bottomCenter),
            //下个数字的下部分,当_isReversePhase为true时才执行翻转动画否则一直和平面呈90度
            Transform(
                transform: Matrix4.identity()
                  ..setEntry(3, 2, 0.006)
                  ..rotateX(_isReversePhase ? -_animation.value : pi / 2),
                alignment: Alignment.topCenter,
                child: ClipRectText(_stateNum + 1, Alignment.bottomCenter)),
          ],
        )
      ],
    )
复制代码
  • 动画实现
 
 _controller = new AnimationController(
        duration: Duration(milliseconds: 450), vsync: this)
      ..addStatusListener((status) {
        //动画正向执行,正向执行结束后进行反向执行
        if (status == AnimationStatus.completed) {
          _controller.reverse();
          _isReversePhase = true;
        }
        //动画反向执行,反向执行结束后一次动画翻转周期结束。当前数字更新到最新的
        if (status == AnimationStatus.dismissed) {
          _isReversePhase = false;
          _stateNum += 1;
        }
      })
      ..addListener(() {
        setState(() {});
      });
    //动画数值使用0度角到90度角
    _animation = Tween(begin: _zeroAngle, end: pi / 2).animate(_controller);
  
复制代码
  • 动画触发条件
@override
  void didUpdateWidget(FlipNumText oldWidget) {
    //当组件的数字num发生改变时执行动画控制器
    if (this.widget.num != oldWidget.num) {
      _controller.forward();
      _stateNum = oldWidget.num;
    }
    super.didUpdateWidget(oldWidget);
  }
复制代码

?完整代码看这里?文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html

最后

翻页动画效果实现中很多运用到了数学算法。如Pi角度、Transform的2D、3D变换、Matrix矩阵使用等都离不开数学计算。目前对于Matrix还只停留在使用上,后续需要深入理解其原理才能更好的运用。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html

作者:JulyYu文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html

文章源自菜鸟学院-https://www.cainiaoxueyuan.com/xcx/16108.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/xcx/16108.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定