flutter AnimationController动画2 AnimatedWidget AnimatedBuilder

这一次我们使用 AnimatedWidget 来实现动画,使用它就不需要给动画 addListener(...) 和 setState((){})了,AnimatedWidget 自己会使用当前 Animation 的 value 来绘制自己。当然,这里 Animation 我们是以构造参数的方式传递进去的。

AnimatedWidget

import 'package:flutter/material.dart';

void main() {
  runApp(SampleApp());
}

class SampleApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Sample App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: AnimateApp(),
    );
  }
}

class AnimateApp extends StatefulWidget {

  @override
  State<StatefulWidget> createState() {
    return _AnimateAppState();
  }
}

class _AnimateAppState extends State<AnimateApp> with SingleTickerProviderStateMixin {

  AnimationController controller;
  Animation<double> animation;
//  Animation<Color> animation;

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

//    线性
    // 创建 AnimationController 对象
    controller = AnimationController(vsync: this, duration: const Duration(milliseconds: 2000));
    // 通过 Tween 对象 创建 Animation 对象
    animation = Tween(begin: 50.0, end: 200.0).animate(controller)
      ..addListener(() {
        // 注意:这句不能少,否则 widget 不会重绘,也就看不到动画效果
        setState(() {});
      });


//     执行动画
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        title: 'AnimateApp',
        theme: ThemeData(
            primaryColor: Colors.blue
        ),
        home: Scaffold(
            appBar: AppBar(
              title: Text('AnimateApp'),
            ),
            body: AnimatedContainer(animation: animation,)

        )
    );
  }

  @override
  void dispose() {
    // 资源释放
    controller.dispose();
    super.dispose();
  }
}

//使用 AnimatedWidget 来实现动画,这里 Animation 我们是以构造参数的方式传递进去的。
class AnimatedContainer extends AnimatedWidget {

  AnimatedContainer({Key key, Animation<double> animation})
      : super (key: key, listenable: animation);

  @override
  Widget build(BuildContext context) {
    final Animation<double> animation = listenable;
    return Center(
      child: Container(
        decoration: BoxDecoration(
            color: Colors.redAccent
        ),
        margin: EdgeInsets.symmetric(vertical: 10.0),
        height: animation.value,
        width: animation.value,
      ),
    );
  }
}

AnimatedBuilder

因为 AnimatedBuilder 是继承于 AnimatedWidget 的,所以可以直接把 AnimatedBuilder 当作 widget 使用

上述代码关键部分如下:

body: Center(
child: AnimatedBuilder(
animation: animation,
child: Container(
decoration: BoxDecoration(color: Colors.redAccent),
),
builder: (context, child) {
return Container(
width: animation.value,
height: animation.value,
child: child,
);
},
),
),

替换body的代码即可,builder 这个匿名类是每次动画值改变的时候就会被调用

 

posted on 2019-12-17 17:37  高彰  阅读(451)  评论(0编辑  收藏  举报

导航