10天学会flutter DAY10 flutter 玩转 动画与打包

      },

    ),

    RaisedButton(

      child: Text("停止"),

      onPressed: () {

        controller.stop();

      },

    )

  ],

);

}

}




> 动画状态监听:在forword结束之后状态为completed。在reverse结束之后状态为dismissed



### [](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)Tween



​ 默认情况下,`AnimationController`对象值为:double类型,范围是0.0到1.0 。如果我们需要不同的范围或不同的数据类型,则可以使用Tween来配置动画以生成不同的范围或数据类型的值。要使用Tween对象,需要调用其`animate()`方法,然后传入一个控制器对象,同时动画过程中产生的数值由`Tween`的`lerp`方法决定。



import ‘package:flutter/material.dart’;

void main() => runApp(AnimationApp());

class AnimationApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

  title: "animation",

  home: Scaffold(

    appBar: AppBar(

      title: Text('animation'),

    ),

    body: AnimWidget(),

  ),

);

}

}

// 动画是有状态的

class AnimWidget extends StatefulWidget {

@override

State createState() {

return _AnimWidgetState();

}

}

class _AnimWidgetState extends State

with SingleTickerProviderStateMixin {

AnimationController controller;

bool forward = true;

Tween tween;

@override

void initState() {

super.initState();



controller = AnimationController(

  // 动画的时长

  duration: Duration(milliseconds: 2000),

  // 提供 vsync 最简单的方式,就是直接继承 SingleTickerProviderStateMixin

  vsync: this,

);

//使用Color

tween = ColorTween(begin: Colors.blue, end: Colors.yellow);

//添加动画值修改监听

tween.animate(controller)..addListener(() => setState(() {}));

}

@override

Widget build(BuildContext context) {

return Column(

  children: <Widget>[

    Container(

      width: 100,

      height: 100,

      //获取动画当前值

      color: tween.evaluate(controller),

    ),

    RaisedButton(

      child: Text("播放"),

      onPressed: () {

        if (forward) {

          controller.forward();

        } else {

          controller.reverse();

        }

        forward = !forward;

      },

    ),

    RaisedButton(

      child: Text("停止"),

      onPressed: () {

        controller.stop();

      },

    )

  ],

);

}

}




### [](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)Curve



​ 动画过程默认是线性的(匀速),如果需要非线形的,比如:加速的或者先加速后减速等。Flutter中可以通过Curve(曲线)来描述动画过程。



import ‘package:flutter/material.dart’;

void main() => runApp(AnimationApp());

class AnimationApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

  title: "animation",

  home: Scaffold(

    appBar: AppBar(

      title: Text('animation'),

    ),

    body: AnimWidget(),

  ),

);

}

}

// 动画是有状态的

class AnimWidget extends StatefulWidget {

@override

State createState() {

return _AnimWidgetState();

}

}

class _AnimWidgetState extends State

with SingleTickerProviderStateMixin {

AnimationController controller;

Animation animation;

bool forward = true;

@override

void initState() {

super.initState();



controller = AnimationController(

  // 动画的时长

  duration: Duration(milliseconds: 2000),

  // 提供 vsync 最简单的方式,就是直接继承 SingleTickerProviderStateMixin

  vsync: this,

);



//弹性

animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);

//使用Color

animation = Tween(begin: 10.0, end: 100.0).animate(animation)

  ..addListener(() {

    setState(() => {});

  });

}

@override

Widget build(BuildContext context) {

return Column(

  children: <Widget>[

    Container(

      //不需要转换

      width: animation.value,

      height: animation.value,

      //获取动画当前值

      color: Colors.blue,

    ),

    RaisedButton(

      child: Text("播放"),

      onPressed: () {

        if (forward) {

          controller.forward();

        } else {

          controller.reverse();

        }

        forward = !forward;

      },

    ),

    RaisedButton(

      child: Text("停止"),

      onPressed: () {

        controller.stop();

      },

    )

  ],

);

}

}




### [](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)AnimatedWidget



​ 通过上面的学习我们能够感受到`Animation`对象本身和UI渲染没有任何关系。而通过`addListener()`和`setState()` 来更新UI这一步其实是通用的,如果每个动画中都加这么一句是比较繁琐的。AnimatedWidget类封装了调用`setState()`的细节,简单来说就是自动调用`setState()`。



​ Flutter中已经封装了很多动画,比如对widget进行缩放,可以直接使用`ScaleTransition`



import ‘package:flutter/material.dart’;

void main() => runApp(AnimationApp());

class AnimationApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return MaterialApp(

  title: "animation",

  home: Scaffold(

    appBar: AppBar(

      title: Text('animation'),

    ),

    body: AnimWidget(),

  ),

);

}

}

// 动画是有状态的

class AnimWidget extends StatefulWidget {

@override

State createState() {

return _AnimWidgetState();

}

}

class _AnimWidgetState extends State

with SingleTickerProviderStateMixin {

AnimationController controller;

Animation animation;

bool forward = true;

@override

void initState() {

super.initState();



controller = AnimationController(

  // 动画的时长

  duration: Duration(milliseconds: 2000),

  // 提供 vsync 最简单的方式,就是直接继承 SingleTickerProviderStateMixin

  vsync: this,

);



//弹性

animation = CurvedAnimation(parent: controller, curve: Curves.bounceIn);

//使用Color

animation = Tween(begin: 10.0, end: 100.0).animate(animation);

}

@override

Widget build(BuildContext context) {

return Column(

  children: <Widget>[

    ScaleTransition(

      child:  Container(

        width: 100,

        height: 100,

        color: Colors.blue,

      ),

      scale: controller,

    ),

    RaisedButton(

      child: Text("播放"),

      onPressed: () {

        if (forward) {

          controller.forward();

        } else {

          controller.reverse();

        }

        forward = !forward;

      },

    ),

    RaisedButton(

      child: Text("停止"),

      onPressed: () {

        controller.stop();

      },

    )

  ],

);

}

}




### [](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)Hero动画



​ Hero动画就是在路由切换时,有一个共享的Widget可以在新旧路由间切换,由于共享的Widget在新旧路由页面上的位置、外观可能有所差异,所以在路由切换时会逐渐过渡,这样就会产生一个Hero动画。



import ‘package:flutter/material.dart’;

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {

@override

Widget build(BuildContext context) {

return new MaterialApp(

  title: 'Flutter Demo',

  home: Scaffold(

      appBar: AppBar(

        title: Text("主页"),

      ),

      body: Route1()),

);

}

}

// 路由A

class Route1 extends StatelessWidget {

@override

Widget build(BuildContext context) {

return Container(

  alignment: Alignment.topCenter,

  child: InkWell(

    child: Hero(

      tag: "avatar", //唯一标记,前后两个路由页Hero的tag必须相同

      child: CircleAvatar(

        backgroundImage: AssetImage(

          "assets/banner.jpeg",

        ),

      ),

    ),

    onTap: () {

      Navigator.push(context, MaterialPageRoute(builder: (_) {

        return Route2();

      }));

    },

  ),

);

}

}

class Route2 extends StatelessWidget {

@override

Widget build(BuildContext context) {

return Center(

  child: Hero(

      tag: "avatar", //唯一标记,前后两个路由页Hero的tag必须相同

      child: Image.asset("assets/banner.jpeg")),

);

}

}




### [](https://docs.qq.com/doc/DSkNLaERkbnFoS0ZF)组合动画



有些时候我们可能会需要执行一个动画序列执行一些复杂的动画。



import ‘package:flutter/material.dart’;

void main() => runApp(MyApp());

  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值