[Flutter动画笔记]-隐式动画

1.隐式动画(全自动)

AnimatedContainer

//比Container多了一个duration属性,
//能改变Container里面的属性,不能改变child里面的
AnimatedContainer
{
duration:Duration(seconds:1), 
//int day,hours,minutes,seconds,millisenconds,microseconds
}

//例子
class _MyHomePageState extends State<MyHomePage> {
  double _height = 200;

  void _incrementCounter() {
    setState(() {
        //按一下加高度100,超过500变回200
      this._height += 100;
      if (this._height > 500) this._height = 200;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: AnimatedContainer(//AnimatedContainer
              duration: Duration(seconds: 1),//动画时间
              height: this._height,
              width: 200,
              color: Colors.blue,
              child: Center(
                child: Text(
                  'Hi',
                  style: TextStyle(fontSize: 30),
                ),
              ))),
      floatingActionButton: FloatingActionButton(
        onPressed: _incrementCounter,
        tooltip: 'Increment',
        child: Icon(Icons.add),
      ),
    );
  }
}


[O]Container-decoration

decoration: BoxDecoration(
    //渐变色
    gradient: LinearGradient(
        //渐变的分界线,0.5-0.7
        stops: [0.5, 0.7],
        colors: [Colors.red, Colors.blue],
        //begin红色跑到下面去,end蓝色跑到上面去
        begin: Alignment.bottomCenter,
        end: Alignment.topCenter),
    
    //阴影 spreadRadius边框大小,blurRadius模糊效果
    boxShadow: [BoxShadow(spreadRadius: 25, blurRadius: 25)],
    
    //圆角边框
    borderRadius: BorderRadius.circular(100)
)

AnimatedSwitcher

//不同控件之间的切换,文字图片等等都行
Center(
    child: AnimatedContainer(
        duration: Duration(seconds: 1),
        height: 200,
        width: 200,
        color: Colors.orange,
        
        child: AnimatedSwitcher(
            duration: Duration(seconds: 2),
            // Center(child: CircularProgressIndicator(),)
            child: 	Image.network('http://www.tobutomi.top/img/example.png'),
        ),
    )),
 

//相同控件之间的切换
//child里面是相同的控件的话,不会有动画的效果,通过key属性解决
//ValueKey
child: AnimatedSwitcher(
    duration: Duration(seconds: 2),
    child:
    //Text('hello', key: ValueKey('hello'), style: TextStyle(fontSize: 30))
    Text('hi', key: ValueKey('hi'), style: TextStyle(fontSize: 30)),
),
)
//UniqueKey
 AnimatedSwitcher(
    duration: Duration(seconds: 2),
    // Text('hello', key: UniqueKey(), style: TextStyle(fontSize: 30)),
    child: Text('hi', key: UniqueKey(), style: TextStyle(fontSize: 30)),
),


//额外属性transitionBuilder
//默认FadeTransition
transitionBuilder: (child, animation) {
    return FadeTransition(
        opacity: animation,
        child: child,
    );
},
//旋转RotationTransition
transitionBuilder: (child, animation) {
    return RotationTransition(
        turns: animation,
        child: child,
    );
},
//缩小放大ScaleTransition
transitionBuilder: (child, animation) {
    return ScaleTransition(
        scale: animation,
        child: child,
    );
},

//嵌套使用
transitionBuilder: (child, animation) {
    return ScaleTransition(
        scale: animation,
        child: FadeTransition(
            opacity: animation,
            child: child,
        ),
    );
},

[O]Opacity

Center(
    child: Opacity(
        //透明度 0-1
        opacity: 0.3,
        child: Container(
            color: Colors.grey,
            height: 200,
            width: 300,
        ),
    )),

AnimatedOpacity

Center(
          child: AnimatedOpacity(
        duration: Duration(seconds: 2),
        //curve属性,默认 curve: Curves.linear线性
        curve: Curves.linear,
        opacity: 0.1,
        child: Container(
          color: Colors.grey,
          height: 200,
          width: 300,
        ),
      )),


AnimatedPadding

AnimatedPadding(
    //curve
    curve: Curves.bounceOut,
    duration: Duration(seconds: 2),
    padding: EdgeInsets.only(top: 300),
    child: Container(
        color: Colors.grey,
        height: 200,
        width: 300,
    ),
),

TweenAnimationBuilder

//补间动画
TweenAnimationBuilder(
    duration: Duration(seconds: 1),
    //begin只是程序运行是生效,后面变化的值在end修改
    tween: Tween(begin: 50.0, end: 100.0), //between 50-100补帧
    builder: (context, value, child) {
        return Container(
            height: 200,
            width: 200,
            color: Colors.blue,
            child: Center(
                child: Text(
                    'hi',
                    //调用value,一开始在50-100变化
                    style: TextStyle(fontSize: value),
                ),
            ),
        );
    },
),

Transform

//Transform.scale 缩放
Center(
    child: Transform.scale(
        //两倍大小
        scale: 2.0,
        child: Text(
            'hi',
            style: TextStyle(fontSize: value),
        ),
    )),



//Transform.rotate 旋转
//angle: 0-6.28  0-2π
child: Center(
    child: Transform.rotate(
        angle: 3.14,
        child: Text(
            'hi',
            style: TextStyle(fontSize: 50),
        ),
    )),


//Transform.translate 平移
//offset Offset(x,y)
//tween:Tween(begin: Offset(0, 0), end: Offset(100, 100)), 
Center(
    child: Transform.translate(
        offset: Offset(-10, 20),
        child: Text(
            'hi',
            style: TextStyle(fontSize: 50),
        ),
    )),

计数器

Center(
          child: Container(
              height: 120,
              width: 300,
              color: Colors.blue,
              child: TweenAnimationBuilder(
                tween: Tween(begin: 7.0, end: 9.0),
                duration: Duration(seconds: 2),
                builder: (context, value, child) {
                    //取整数
                  final whole = value ~/ 1;
                    //取小数(进度)
                  final decimal = value - whole;
                  // print('${whole}:${decimal}');
                  return Stack(
                    children: [
                      Positioned(
                        top: -100 * decimal, //0 -> -100
                        child: Opacity(
                          opacity: 1.0 - decimal, //1 -> 0
                          child: Text('$whole',
                              style: TextStyle(
                                  color: Colors.white, fontSize: 100)),
                        ),
                      ),
                      Positioned(
                          top: 100 - decimal * 100, //100 -> 0
                          child: Opacity(
                            opacity: decimal, //0 -> 1
                            child: Text(
                              '${whole + 1}',
                              style:
                                  TextStyle(color: Colors.white, fontSize: 100),
                            ),
                          ))
                    ],
                  );
                },
              ))),

second version

class _MyHomePageState extends State<MyHomePage> {
  int _count = 0;
  _increment() {
    setState(() {
      this._count++;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
          child: Container(
        height: 120,
        width: 100,
        child: AnimatedCounter(
          value: 1,
          duration: Duration(seconds: 1),
        ),
      )),
      floatingActionButton: FloatingActionButton(
        onPressed: _increment,
        child: Icon(Icons.add),
      ),
    );
  }
}

AnimatedCounter

import 'package:flutter/material.dart';

class AnimatedCounter extends StatelessWidget {
  final Duration duration;
  final int value;
  AnimatedCounter({@required this.value, @required this.duration});
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return TweenAnimationBuilder(
      tween: Tween(end: this.value.toDouble()),
      duration: this.duration,
      builder: (context, value, child) {
        final whole = value ~/ 1;
        final decimal = value - whole;
        // print('${whole}:${decimal}');
        return Stack(
          children: [
            Positioned(
              top: -100 * decimal, //0 -> -100
              child: Opacity(
                opacity: 1.0 - decimal, //1 -> 0
                child: Text('$whole',
                    style: TextStyle(color: Colors.black, fontSize: 50)),
              ),
            ),
            Positioned(
                top: 100 - decimal * 100, //100 -> 0
                child: Opacity(
                  opacity: decimal, //0 -> 1
                  child: Text(
                    '${whole + 1}',
                    style: TextStyle(color: Colors.black, fontSize: 50),
                  ),
                ))
          ],
        );
      },
    );
  }
}

上一篇:获取input上传的视频的长度


下一篇:使用k6.io进行性能测试与压力测试,并生成优雅的可视化报告