Flutter - 内置动画 API

Flutter 内置动画

上面的那些通常用起来不是很方便,即使是 AnimatedBuilder 仍是要指定参与动画变化的 widget 属性,为了进一步方便咱们,官方在 AnimatedWidget 的基础上封装了下面这些内置动画库,就是 android 中的那些,固然更多一些:android

  • SlideTransition - 自身倍数位移动画
  • AlignTransition - 没找到资料
  • PositionedTransition - 缩放动画,限定父布局只能是 stack
  • FadeTransition - 透明度动画
  • ScaleTransition - 缩放动画,这个是 android 中的那种缩放动画,能够指定中心点
  • SizeTransition - 宽高动画,限制是每次只能执行一个维度的动画,宽和高一块儿不行,那就是缩放动画了
  • RotationTransition - 旋转动画,特色是其数值是 0-1 之间的,旋转90度 = 0.25

这些 transition 的特色就是,用一个参数接受 animation 动画,child 写 widgetide


FadeTransition

FadeTransition 是透明度动画,参数就是一个 opacity 指定动画,child 写 widget 就没了布局

animationController = AnimationController(
  duration: Duration(milliseconds: 300),
  vsync: this,
);

animation = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut);
animation = Tween(begin: 0.0, end: 1.0).animate(animationController);
复制代码
Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          FadeTransition(
            opacity: animation,
            child: Container(
              margin: EdgeInsets.only(bottom: 20),
              width: 300,
              height: 300,
              color: Colors.blueAccent,
            ),
          ),
          RaisedButton(
            child: Text("放大"),
            onPressed: () {
              animationController?.forward();
            },
          ),
        ],
      ),
    );
  }
}
复制代码

SlideTransition

SlideTransition 位移动画,使用 offset 来承载x,y轴数据。须要注意的是 Offset(0.0, 0.0) 中的数值都是 倍数,也就是说 SlideTransition 只支持按 widget 自己长宽的倍数位移,不支持具体的数值的位移操做动画

void initState() {
    super.initState();

    animationController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this,
    );

    animation = Tween(begin: Offset(0.0, 0.0), end: Offset(1.0, 1.0))
        .animate(animationController);
  }
复制代码
Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SlideTransition(
            position: animation,
            child: Container(
              margin: EdgeInsets.only(bottom: 20),
              width: 100,
              height: 100,
              color: Colors.blueAccent,
            ),
          ),
          RaisedButton(
            child: Text("放大"),
            onPressed: () {
              animationController?.forward();
            },
          ),
        ],
      ),
    );
  }
复制代码

PositionedTransition

PositionedTransition 缩放动画,必须在 stack 中使用,其缩放数值使用 RelativeRect 包裹,先后变化的是距 stack 父布局左上右下4个角的距离:ui

animation = RelativeRectTween(
            begin: RelativeRect.fromLTRB(0, 0, 0, 0),
            end: RelativeRect.fromLTRB(50, 200, 50, 200))
        .animate(animationController);
复制代码

你们看个图: this

基本上就是这个思路了,限制有一些,下面是例子代码,不是上面 gif 的代码:spa

Animation<RelativeRect> animation;
  AnimationController animationController;
  CurvedAnimation curve;

  void initState() {
    super.initState();

    animationController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this,
    );

    curve = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut);
    
    animation = RelativeRectTween(
            begin: RelativeRect.fromLTRB(0, 0, 0, 0),
            end: RelativeRect.fromLTRB(50, 200, 50, 200))
        .animate(curve);
  }
复制代码
Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          PositionedTransition(
            rect: animation,
            child: Container(
              width: 300,
              height: 300,
              color: Colors.blueAccent,
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
复制代码

最后你们注意啊,RelativeRectTween begin 的数值能影响 widget 初始显示时的宽高大小code


ScaleTransition

ScaleTransition 这才是传统的缩放动画,使用 alignment: Alignment.topLeft 指定缩放中心点cdn

Animation<double> animation;
  AnimationController animationController;
  CurvedAnimation curve;

  @override
  void initState() {
    super.initState();

    animationController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this,
    );

    curve =
        CurvedAnimation(parent: animationController, curve: Curves.bounceInOut);
    animation = Tween(
      begin: 1.0,
      end: 0.3,
    ).animate(curve);
  }

复制代码
Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          ScaleTransition(
            alignment: Alignment.topLeft,
            scale: animation,
            child: Container(
              width: 300,
              height: 300,
              color: Colors.blueAccent,
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
复制代码

SizeTransition

SizeTransition 宽高动画,限制是每次只能设定一个维度,不能宽和高一块儿,优势是宽高的变化不会引发内容的变形blog

axis: Axis.horizontal 就是指定动画做用与宽仍是高

Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          SizeTransition(
            axis: Axis.horizontal,
            sizeFactor: animation,
            child: Container(
              color: Colors.blueAccent,
              child: Icon(Icons.access_alarm, size: 300),
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
复制代码

RotationTransition

RotationTransition 旋转动画,特色是其数值是 0-1 之间的,旋转90度 = 0.25,依然能够设置原点

animation = Tween(
  begin: 0.0,
  end: 0.25,
).animate(curve);
复制代码
Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          RotationTransition(
            turns: animation,
            alignment: Alignment.center,
            child: Container(
              color: Colors.blueAccent,
              child: Icon(Icons.access_alarm, size: 300),
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
复制代码
相关文章
相关标签/搜索