美文网首页
flutter 四布局开发2-动画

flutter 四布局开发2-动画

作者: crossroads | 来源:发表于2025-01-01 19:16 被阅读0次

一、变换Transform

对其子部件应用各种变换,例如平移(Translation)、旋转(Rotation)、缩放(Scale)
1. 缩放

Transform.scale(
   scale: 0.5,
   child: Container(
      padding: const EdgeInsets.all(8.0),
      color: const Color(0xFFE8581C),
      child: const Text('Bad Idea Bears'),
  ),
)
  1. 旋转
Transform.rotate(
            angle: 30 * (pi / 180),//30度
            origin: Offset(50,50),//默认中心,这里设置右下角
            child: Container(
              padding: const EdgeInsets.all(8.0),
              color: Colors.green,
              width: 100,
              height: 100,
            ),
          )

3. 组合

    var combinedMatrix = Matrix4.identity();
    combinedMatrix.scale(1.5, 1.5, 1.0); // 缩放
    combinedMatrix.rotateZ(0.3); // 旋转
    combinedMatrix.translate(10.0, 20.0, 0.0); // 平移
   Transform(
            transform: combinedMatrix,
            child: Container(
              width: 100,
              height: 100,
              color: Colors.blue,
            ),
  ),
Transform(
            alignment: Alignment(0.5, 0),
            transform: Matrix4.identity()
              ..scale(_scaleAnimation.value)
              ..rotateZ(_scaleAnimation.value * 3.14),
            child: Container(
              padding: const EdgeInsets.all(8.0),
              color: const Color(0xFFE8581C),
              width: 100,
              height: 100,
            ),
          )

4. 变换原点
默认的变换原点是被变换部件的左上角(0,0)位置
以中心为原点

Transform(
    alignment: Alignment.center,
    transform: combinedMatrix,
    child: Container(
        width: 100,
        height: 100,
        color: Colors.green,
    ),
)

自定义原点位置
Alignment的坐标中,(0.0, 0.0) 表示部件的中心位置(水平和垂直方向的中心)。水平方向上,-1.0 表示最左边,1.0 表示最右边;垂直方向上,-1.0 表示最上边,1.0 表示最下边(可以自己画一个,x轴向右,Y轴向下的坐标轴)

 Transform.scale(
...
            alignment: Alignment(0, -1.0),
          )

二、动起来

1. 最简单的AnimatedContainer

Column(
          children: [
            GestureDetector(
              child: Text('text'),
              onTap: () {
                setState(() {
                  width = width * 2;
                });
              },
            ),
            AnimatedContainer(
              duration: Duration(seconds: 3),
              child: Container(
                color: Colors.blueAccent,
              ),
              width: width,
              height: width,
            ),
          ],
        )

2. 使用AnimatedBuilder、AnimationController和Tween实现动画

  1. 单个动画
 late AnimationController _controller;
  late Animation<double> _animation;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this,
      duration: Duration(seconds: 2),
    );
    _animation = Tween<double>(begin: 1.0, end: 1.2).animate(_controller);
    _controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.only(left: 60),
      child: AnimatedBuilder(
        animation: _controller,
        builder: (BuildContext context, Widget? child) {
          return Transform.scale(
            scale: _animation.value,
            alignment: Alignment(0, -1.0),
            child: Container(
              width: 100,
              height: 100,
              color: Colors.blue,
            ),
          );
        },
      ),
    );
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }
  1. 多个动画
    先放大再缩小
    _scaleController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 300),
    );
 _scaleAnimation = Tween<double>(begin: 0.0, end: 1.1).animate(CurvedAnimation(
      parent: _scaleController,
      curve: const Interval(0.0, 2 / 3, curve: Curves.linear),
    ));
  
   _scaleController.addListener(() {
      if (_scaleController.value >= 2 / 3) {
        _scaleAnimation = Tween<double>(begin: 1.1, end: 1.0).animate(CurvedAnimation(
          parent: _scaleController,
          curve: const Interval(2 / 3, 1, curve: Curves.linear),
        ));
      }
    });
    // 启动动画
    _animationController.forward();
AnimatedBuilder(
          animation: _scaleAnimation,
          builder: (BuildContext context, Widget? child) {
            return Transform.scale(
              scale: _scaleAnimation.value,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
              ),
            );
          },
        ),
  1. 另一种方式:TweenSequenceItem多个动画
 _scaleController = AnimationController(
      vsync: this,
      duration: const Duration(milliseconds: 750),
    );

    _scaleAnimation = TweenSequence([
      TweenSequenceItem(
        tween: Tween<double>(begin: 0.0, end: 1.1).chain(CurveTween(curve: Curves.linear)),
        weight: 2 / 3,
      ),
      TweenSequenceItem(
        tween: Tween<double>(begin: 1.1, end: 1.0).chain(CurveTween(curve: Curves.linear)),
        weight: 1 / 3,
      ),
    ]).animate(_scaleController);

    _scaleController.addListener(() {
      setState(() {});
    });

  1. 当需要控制原点,却不知道子控件大小情况
    [本想用AnimatedBuilder,但是不行,不得不setState,后续有其他方案了再更新]
    _scaleController.addListener(() {
      setState(() {});//这样RenderBox才能获取到值
    });
...
    RenderBox? renderBox = context.findRenderObject() as RenderBox?;
    Size size = renderBox?.size ?? Size.zero;
Transform.scale(
          scale: scale,
          alignment: Alignment(centerOffsetX / (size.width / 2), -1.0),
          child: child,
        )

三、Matrix4

  1. 变形
  _skewAnimation = Tween<double>(begin: 0, end: 0.2).animate(
        _animationController
    );
AnimatedBuilder(
            animation: _skewAnimation,
            builder: (context, child) {
              return Transform(
                transform: Matrix4.skewY(_skewAnimation.value),
                child: Container(
                  width: 100,
                  height: 100,
                  color: Colors.green,
                ),
              );
            },
          )

后记

AnimatedContainer:适合简单的属性动画,不需要管理复杂的动画控制器,方便快捷地实现常见属性的动画效果。
AnimatedBuilder:适用于更复杂的动画,将动画逻辑和 UI 构建分离,使得代码更具可维护性和可扩展性。
Hero:用于页面间共享元素的过渡动画,提供流畅的页面切换体验,增强用户界面的连贯性和视觉效果

相关文章

  • 8. Card

    Card布局 Flutter布局中的Card布局,类似于Android开发中的CardView布局

  • 7. Stack布局

    1. Stack布局 Flutter中的Stack布局方式,类似于Android开发中的FrameLayout布局...

  • Flutter轮播图

    前端开发当中最有意思的就是实现动画特效,Flutter提供的各种动画组件可以方便实现各种动画效果。Flutter中...

  • Flutter 基本组件ListlView

    Flutter 列表组件 列表布局是我们项目开发中最常用的一种布局方式。Flutter 中我们可以通过 ListV...

  • flutter九宫格看图

    flutter九宫格图片 利用GridView实现布局,用Hero动画进行展示

  • flutter 基础 01

    1. 开始 2. flutter 布局部分 笔记 3. flutter 动画部分的一些概念(根据个人理解来写的, ...

  • Flutter 布局

    Flutter 布局详解 Flutter 布局(一)- Container详解 Flutter 布局(二)- Pa...

  • Flutter 119: 图解简易 ACEFrameAnimat

    小菜在做 Android 开发时,常常需要 帧动画 来作为作为 loading 动画;而 Flutter 没有直接...

  • Flutter-内置的动画组件

    在Flutter的动画开发当中,Flutter SDK也有提供一些内置的动画组件给我们使用。这篇博客就来分享一下有...

  • Flutter-布局

    一、介绍 flutter布局需要先了解flutter所有布局的widget,首先flutter布局分为Contai...

网友评论

      本文标题:flutter 四布局开发2-动画

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