当前位置: 代码网 > it编程>编程语言>C/C++ > Flutter动画详解第二篇之显式动画(Explicit Animations)

Flutter动画详解第二篇之显式动画(Explicit Animations)

2024年08月01日 C/C++ 我要评论
这里是Flutter动画系列的第二篇。例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。

目录

前言

一、定义

1.animationcontroller

1.常用属性

1. value

2. status

3. duration

2.常用方法

1.forward

2.reverse

3.repeat

4.stop

5. reset

6. animateto(double target, {duration? duration, curve curve = curves.linear})

7.animateback(double target, {duration? duration, curve curve = curves.linear})

8. addlistener(voidcallback listener)

10.addstatuslistener(animationstatuslistener listener)

11. removestatuslistener(animationstatuslistener listener)

        移除状态监听器。

2.animation

3.tween

4.listeners

5.builders

二、常见的显示动画组件

1.rotationtransition       

2.fadetransition

3.scaletransition

4.slidetransition

三、自定义显式动画

四、参考文章


前言

    上一篇文章介绍了flutter中的隐式动画的用法。

    我们会发现隐式动画使用起来非常的方便,我们只需要设置动画的旧值变化之后的值,flutter会帮助我们完整动画的中间过程。flutter中隐式动画的实现是全自动的。

     今天我们介绍下flutter中的显式动画。

一、定义

        在flutter中,显式动画(explicit animations)指的是那些需要你手动控制动画过程的动画。显式动画提供了更多的控制权,但也需要更多的代码和管理。显式动画通常涉及到以下几个核心组件:

  1. animationcontroller
  2. animation
  3. tween
  4. listeners
  5. builders

            核心组件的详解如下:

1.animationcontroller

        animationcontroller是 flutter 动画框架的核心部分之一,用于控制动画的播放、停止、前进、倒退等。它提供了丰富的 api 来管理和控制动画的行为。下面是 animationcontroller的一些常用 api 及其解释:

1.常用属性

1. value

        当前动画的值。可以是 `double` 类型,表示动画当前的进度。

2. status

        当前动画的状态,是animationstatus枚举类型,可能的值有dismissed、forward、reverse 和 completed。

3. duration

        动画的时长。

4. upperbound和 lowerbound

       动画的范围。

2.常用方法

1.forward

        动画正向执行,从lowerbound到upperbound。

2.reverse

        动画反向执行,从upperbound到lowerbound

3.repeat

        重复执行动画,可以指定周期和是否反向。

4.stop

        停止动画。

5. reset

        重置动画到 `lowerbound`,并停止动画。

6. animateto(double target, {duration? duration, curve curve = curves.linear})

        动画执行到指定值。

7.animateback(double target, {duration? duration, curve curve = curves.linear})

        动画反向执行到指定值。

8. addlistener(voidcallback listener)

        添加监听器,每次动画值改变时调用。

9. removelistener(voidcallback listener)

        移除监听器。

10.addstatuslistener(animationstatuslistener listener)

        添加状态监听器,动画状态改变时调用。

11. removestatuslistener(animationstatuslistener listener)
        移除状态监听器。

2.animation

        在 flutter 中,显式动画需要开发者手动管理动画的每个步骤,其中 animation 类是核心组件之一。animation 类本身是一个抽象类,它定义了动画的当前值和状态,并且可以被监听以响应动画的变化。通过 animation 类,开发者可以访问动画的值并将其应用到 ui 元素上。

        在实际做动画的过程中,我们会用到各种各样的animation。例如我们做缩放动画的时候,animation的类型为double类型,渐变动画的时候,animation可以表示颜色的动画,平移动画的时候,animation可以表示平移的大小。

3.tween

        定义动画的开始和结束值。常见的有 tween<double>、colortween 等。

4.listeners

        通过 addlistener 和 addstatuslistener 可以监听动画的每一帧和动画状态的变化。

5.builders

        通过 animatedbuilder 或 custompainter 等将动画值应用到ui上。

二、常见的显示动画组件

        显示动画都以transition结尾。常见的显示动画有rotateanimation动画、fadetransition、scaletransition、slidetransition、animatedicon。在显示动画中,我们通过animatedcontroller控制动画的开始、暂停、重置、跳转、倒播等。

1.rotationtransition       

        rotationtransition主要用来做旋转动画。

        我们以下面的效果为例,看看如何使用rotationtransition动画。

        图1.rotationtransition动画

        我们要做一个不停旋转的flutterlogo。

        首先我们设置flutterlogo的大小为60。

        我们要做一个不停旋转的显式动画,因此我们需要再flutterlogo的外面使用rotationtransition包裹起来。

代码如下:

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('rotateanimation动画'),
      ),
      body: center(
        child: rotationtransition(
          turns: controller,
          child: const flutterlogo(
            size: 60,
          ),
        ),
      ),
    );
  }

        我们看一下rotatintransition的定义:

  const rotationtransition({
    super.key,
    required animation<double> turns,
    super.alignment = alignment.center,
    super.filterquality,
    super.child,
  }) : super(animation: turns, ontransform: _handleturnsmatrix);

        这里必须要传递animationcontroller对象。因此我们在定义animationcontroller。

           为了让程序和手机的刷新频率保持一致,我们的stateful后面要实现singletickerproviderstatemixin。

        代码如下:

class _rotateanimationdemosstate extends state<rotateanimationdemos> with singletickerproviderstatemixin{
      // 定义animationcontroller
  late animationcontroller controller;
}

        然后我们widget的初始化方法中,初始化我们的animationcontroller。

        这里我们设置下动画的时长,vsync参数传this。表示当前app和手机刷新的频率保持一致。

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller = animationcontroller(duration: const duration(seconds: 3), vsync: this);
  }

            ok.到这里之后,完整的代码如下:

import 'package:flutter/material.dart';

class rotateanimationdemos extends statefulwidget {
  const rotateanimationdemos({super.key});

  @override
  state<rotateanimationdemos> createstate() => _rotateanimationdemosstate();
}

class _rotateanimationdemosstate extends state<rotateanimationdemos>
    with singletickerproviderstatemixin {
  // 定义animationcontroller
  late animationcontroller controller;

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller =
        animationcontroller(duration: const duration(seconds: 3), vsync: this);
  }

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('rotateanimation动画'),
      ),
      body: center(
        child: rotationtransition(
          turns: controller,
          child: const flutterlogo(
            size: 60,
          ),
        ),
      ),
    );
  }
}

        运行代码之后,页面加载出来了,但是flutterlogo没有转起来。

        因为显式动画是手动控制动画的播放,因此我们还需要手动调用下animationcontroller的repeat方法。

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller = animationcontroller(duration: const duration(seconds: 3), vsync: this)..repeat();
  }

        再次运行,就发现flutterlogo旋转起来了。

完整代码如下:

import 'package:flutter/material.dart';

class rotateanimationdemos extends statefulwidget {
  const rotateanimationdemos({super.key});

  @override
  state<rotateanimationdemos> createstate() => _rotateanimationdemosstate();
}

class _rotateanimationdemosstate extends state<rotateanimationdemos>
    with singletickerproviderstatemixin {
  // 定义animationcontroller
  late animationcontroller controller;

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller = animationcontroller(duration: const duration(seconds: 3), vsync: this)..repeat();
  }

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('rotateanimation动画'),
      ),
      body: center(
        child: rotationtransition(
          turns: controller,
          child: const flutterlogo(
            size: 60,
          ),
        ),
      ),
    );
  }
}

        上述调用了animationcontroller的repeat方法,animationcontroller还提供了forward、reverse、stop、reset等常用方法,它们的含义如下:

  1. forward:动画仅执行一次
  2. reverse:动画倒序执行一次
  3. stop:动画停止
  4. reset:动画重置
  5. repeat:重复的执行动画

        如果感兴趣,可以逐个调用这些方法看看效果。

2.fadetransition

        fadetransition用于制作透明度动画。

        fadetransition和rotationtransition的用法基本差不多。

        下面的例子中,展示了使用fadetransition制作动画的过程。

        图2.fadetransition动画

        完整代码如下:

import 'package:flutter/material.dart';

class fadeanimationdemos extends statefulwidget {
  const fadeanimationdemos({super.key});

  @override
  state<fadeanimationdemos> createstate() => _fadeanimationdemosstate();
}

class _fadeanimationdemosstate extends state<fadeanimationdemos> with singletickerproviderstatemixin{
  // 定义animationcontroller
  late animationcontroller controller;

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller = animationcontroller(
        duration: const duration(seconds: 1),
        vsync: this,
        lowerbound: 0.1,
         upperbound: 1.0,
    )..repeat();
  }

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('fadetransition动画'),
      ),
      body: center(
          child:fadetransition(
            opacity: controller,
            child: const flutterlogo(size: 200,),
          ),
      ),
    );
  }
}

3.scaletransition

        scaletransition用于制作缩放动画,依然可以使用animationcontroller更加精准的控制动画的细节。

        图3.缩放动画

        完整代码如下:

import 'package:flutter/material.dart';

class scaletransitiondemos extends statefulwidget {
  const scaletransitiondemos({super.key});

  @override
  state<scaletransitiondemos> createstate() => _scaletransitiondemosstate();
}

class _scaletransitiondemosstate extends state<scaletransitiondemos> with singletickerproviderstatemixin{
  // 定义animationcontroller
  late animationcontroller controller;

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller = animationcontroller(
      duration: const duration(seconds: 1),
      vsync: this,
      lowerbound: 0.1,
      upperbound: 1.0,
    )..repeat();
  }

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('scaletransition动画'),
      ),
      body: center(
        child:scaletransition(
          scale: controller,
          child: container(
            width: 100,
            height: 100,
            color: colors.deeppurpleaccent,
          ),
        ),
      ),
    );
  }
}

4.slidetransition

        slidetransition用于做平移动画。

        下图是使用slidetransition制作的平移动画。

图4.slidetransition动画

        完整代码如下:

import 'package:flutter/material.dart';

class slidetransitiondemos extends statefulwidget {
  const slidetransitiondemos({super.key});

  @override
  state<slidetransitiondemos> createstate() => _slidetransitiondemosstate();
}

class _slidetransitiondemosstate extends state<slidetransitiondemos> with singletickerproviderstatemixin{
  // 定义animationcontroller
  late animationcontroller controller;

  //初始化 animationcontroller
  @override
  void initstate() {
    super.initstate();
    //vsync: 让程序和手机的刷新频率统一
    controller = animationcontroller(
      duration: const duration(seconds: 1),
      vsync: this,
      lowerbound: 0.1,
      upperbound: 1.0,
    )..repeat();
  }

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('slidetransition动画'),
      ),
      body: center(
        child:slidetransition(
          position: controller.drive(tween(begin: const offset(0, 0), end: const offset(0.5, 0))),
          child: const flutterlogo(size: 200,),
        ),
      ),
    );
  }
}

        我们还可以使用animationcontroller的drive方法修改动画的初始值。

        例如在下面的缩放动画代码中,开始的时候,长度和宽度都是从0.5倍开始,2倍结束。

        部分代码如下:

center(
        child:scaletransition(
          scale: controller.drive(tween(begin: 0.5, end: 2.0)),
          child: container(
            width: 100,
            height: 100,
            color: colors.deeppurpleaccent,
          ),
        ),
      )

        还可以调用animationcontroller的chain方法叠加动画的曲线。

三、自定义显式动画

        这里我们看一下如何自定义显式动画。

        例如我们这里有一个透明度为0.9的container组件,代码如下:

import 'package:flutter/material.dart';

class customexplicitpage extends statefulwidget {
  const customexplicitpage({super.key});

  @override
  state<customexplicitpage> createstate() => _customexplicitpagestate();
}

class _customexplicitpagestate extends state<customexplicitpage> with singletickerproviderstatemixin {
  late animationcontroller _controller;

  @override
  void initstate() {
    super.initstate();
    _controller = animationcontroller(vsync: this);
  }

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

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('自定义显示动画'),
      ),
      body: center(
        child: opacity(
          opacity: 0.9,
          child: container(
            alignment: alignment.center,
            color: colors.deeppurpleaccent,
            width: 250,
            height: 250,
            child: const text('hi',style: textstyle(fontsize: 24),),
          ),
        ),
      ),
    );
  }
}

        我们看下如何使用animatedbuilder实现自定义显式动画。

        首先我们把需要制作动画的widget的外层包裹一个animatedbuilder。builder函数内部返回要操作的widget,把animatedcontroller传给animatedbuilder的animation属性。

        部分代码如下:

center(
        child: animatedbuilder(
          animation: _controller,
          builder: (buildcontext context, widget? child) {
            return opacity(
              opacity: 0.9,
              child: container(
                alignment: alignment.center,
                color: colors.deeppurpleaccent,
                width: 250,
                height: 250,
                child: const text('hi',style: textstyle(fontsize: 24),),
              ),
            );
          },
        ),
      )

             然后调用animationcontroller的repeat方法,一个自定义的显式动画就实现了。

        完整代码如下:

import 'package:flutter/material.dart';

class customexplicitpage extends statefulwidget {
  const customexplicitpage({super.key});

  @override
  state<customexplicitpage> createstate() => _customexplicitpagestate();
}

class _customexplicitpagestate extends state<customexplicitpage> with singletickerproviderstatemixin {
  late animationcontroller _controller;

  @override
  void initstate() {
    super.initstate();
    _controller = animationcontroller(vsync: this,duration: const duration(seconds: 2))..repeat();
  }

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

  @override
  widget build(buildcontext context) {
    return scaffold(
      appbar: appbar(
        title: const text('自定义显示动画'),
      ),
      body: center(
        child: animatedbuilder(
          animation: _controller,
          builder: (buildcontext context, widget? child) {
            return opacity(
              opacity: _controller.value,
              child: container(
                alignment: alignment.center,
                color: colors.deeppurpleaccent,
                width: 250,
                height: 250,
                child: const text('hi',style: textstyle(fontsize: 24),),
              ),
            );
          },
        ),
      ),
    );
  }
}

        完整的效果如下:

        图5.自定义显式动画

四、参考文章

1.教程 | flutter 中文文档 - flutter 中文开发者网站 - flutter

    

        

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com