美文网首页Flutter圈子Flutter 入门与实战
来,滑动到下一个小姐姐!

来,滑动到下一个小姐姐!

作者: 岛上码农 | 来源:发表于2022-04-24 20:30 被阅读0次

    前言

    我们开始来介绍转换类的动画组件,实际上这类转换动画组件也可以自己通过 AnimatedBuilderAnimatedWidget 完成, Flutter 为了简化开发,提供了不少转换动画组件,这类组件通常命名为 xxTransition。本篇要介绍的就是 SlideTransition,顾名思义,就知道是滑动转换动画。我们本篇来实现两张小姐姐图片的滑动切换,效果如下图所示。

    SlideTransition.gif

    SlideTransition 介绍

    SlideTransition 实际上是 AnimatedWidget 子类,其构造方法定义如下:

    const SlideTransition({
      Key? key,
      required Animation<Offset> position,
      this.transformHitTests = true,
      this.textDirection,
      this.child,
    })
    

    其中 position 是关键参数,他表示一个位置偏移的动画,实际上就是通过修改子组件的位置偏移量来完成滑动动画效果的。回顾一下我们 AnimatedWidget 的使用的介绍:Flutter 实现 3D 动画效果详解。只要我们通过一个 AnimationController 控制 Animation 对象就可以实现动画的控制。使用 SlideTransition 也是一样。我们想要实现组件滑动,那就使用 AnimationController 控制一个 Animation<Offset> 对象就可以了。这里需要注意,position 设定的位置便宜是一个比例参数,即位置是子组件的尺寸乘以 Offset 对象的值。

    new_x = width * dx;
    new_y = height * dy;
    

    比如我们想让组件从左边滑入,那么可以设置 dx 为负值;而如果是想从右边滑入,那么可以设置 dx 为正值。同理,想上滑入或下滑入也是一样,只是调整 dy 的值就可以了。而通过 dxdy 的组合,就可以实现斜线方向的滑入滑出效果了。

    示例效果实现

    示例动效实际上我们使用的是一个 Stack 组件,将两张图片分别作为两个 SlideTransition 的子组件层叠在一起。而把那张未出现的图片的初始横向位置设置在左侧显示区域外。当启动动画的时候,之前显示的图片的横向位置调整到右侧显示区域外,从而实现右侧滑出效果;原先在左侧显示区域外的图片的横向位置调整到0,使得占据之前图片的位置,从而实现左侧滑入的效果。点击按钮的时候,就是控制 AnimationControllerforward方法驱动动画,然后再次点击到时候调用 reverse 方法恢复即可。代码如下:

    class SlideTransitionDemo extends StatefulWidget {
      SlideTransitionDemo({Key? key}) : super(key: key);
    
      @override
      _SlideTransitionDemoState createState() => _SlideTransitionDemoState();
    }
    
    class _SlideTransitionDemoState extends State<SlideTransitionDemo>
        with SingleTickerProviderStateMixin {
      bool _forward = true;
      final begin = Offset.zero;
      // 第一张图片结束位置移出右侧屏幕
      final end1 = Offset(1.1, 0.0);
      // 第二张图片的初始位置在左侧屏幕
      final begin2 = Offset(-1.1, 0.0);
      late Tween<Offset> tween1 = Tween(begin: begin, end: end1);
      late Tween<Offset> tween2 = Tween(begin: begin2, end: begin);
    
      late AnimationController _controller =
          AnimationController(duration: const Duration(seconds: 1), vsync: this);
    
      //使用自定义曲线动画过渡效果
      late Animation<Offset> _animation1 = tween1.animate(
        CurvedAnimation(
          parent: _controller,
          curve: Curves.easeInOut,
        ),
      );
      late Animation<Offset> _animation2 = tween2.animate(CurvedAnimation(
        parent: _controller,
        curve: Curves.easeInOut,
      ));
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(
            title: Text('SlideTransition'),
            brightness: Brightness.dark,
            backgroundColor: Colors.black,
          ),
          backgroundColor: Colors.black,
          body: Center(
            child: Container(
              padding: EdgeInsets.all(10.0),
              child: Stack(
                children: [
                  SlideTransition(
                    child: ClipOval(
                      child: Image.asset('images/beauty.jpeg'),
                    ),
                    position: _animation1,
                  ),
                  SlideTransition(
                    child: ClipOval(
                      child: Image.asset('images/beauty2.jpeg'),
                    ),
                    position: _animation2,
                  ),
                ],
              ),
            ),
          ),
          floatingActionButton: FloatingActionButton(
            child: Icon(Icons.swap_horizontal_circle_sharp),
            onPressed: () {
              setState(() {
                if (_forward) {
                  _controller.forward();
                } else {
                  _controller.reverse();
                }
                _forward = !_forward;
              });
            },
          ),
        );
      }
    }
    

    总结

    本篇介绍了 SlideTransition 转换动画类及其应用。通过 SlideTransition 我们还可以实现很多其他动画效果,例如图片浏览、滑动卡片等。

    相关文章

      网友评论

        本文标题:来,滑动到下一个小姐姐!

        本文链接:https://www.haomeiwen.com/subject/yqcxyrtx.html