flutter3.0学习笔记

AnimatedContainer

Preview
  • AnimatedContainer(隐式动画)

AnimatedContainer(隐式动画)

AnimatedContainer可以说是带动画的容器,使用AnimatedContainer可以很方便的实现Widget的动画效果。

因为 AnimatedContainer 是隐式动画,所以不需要控制器来控制动画。

AnimatedContainer只需要提供动画开始值和结束值,它就会动起来并不需要我们主动调用setState方法。

  • 构造函数
 AnimatedContainer({
    super.key,
    this.alignment,
    this.padding,
    Color? color,
    Decoration? decoration,
    this.foregroundDecoration,
    double? width,
    double? height,
    BoxConstraints? constraints,
    this.margin,
    this.transform,
    this.transformAlignment,
    this.child,
    this.clipBehavior = Clip.none,
    super.curve,
    required super.duration,//必须
    super.onEnd,//结束动画
  }) 

例子: 隐式动画不需要创建动画控制器,例子的控制器是球弹跳动画的。

import 'package:flutter/material.dart';

class AnimatedContainerPage extends StatefulWidget {
  const AnimatedContainerPage({Key? key}) : super(key: key);

  @override
  State<AnimatedContainerPage> createState() => _AnimatedContainerPageState();
}

class _AnimatedContainerPageState extends State<AnimatedContainerPage> with SingleTickerProviderStateMixin {
  late AnimationController _controller;
  late Animation<double> _animation;
  //用户点击时启动动画
  bool isAnimating = false;
  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    _controller = AnimationController(
        duration: const Duration(milliseconds: 500),
        vsync: this
    )..repeat(reverse: true);
    final curvedAnimation = CurvedAnimation(
        parent: _controller,
        curve: Curves.fastOutSlowIn
    );
    //通过Tween来生成不同的区间范围值,Tween不保存任何状态,它只是起始值的变换函数。
    _animation = Tween<double>(begin:0 ,end: -300).animate(curvedAnimation);
    _controller.addListener(() {
      //监听插值变化
      setState(() {
       // print(_animation.value);
      });
    });
  }

  @override
  void dispose() {
    // TODO: implement dispose
    _controller.dispose();
    super.dispose();
  }
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('AnimatedContainer'),),
      body: SafeArea(
        child: Stack(
          children: [
            Positioned(
              bottom: 0,
              left: 0,
              right: 0,
              child: Column(
                children: [
                  Transform.translate(
                    offset:  Offset(0,_animation.value),
                    child: Image.asset(
                      'images/qiu.png',
                      fit: BoxFit.contain,
                      height: 70,
                      width: 70,
                    ),
                  ),
                  GestureDetector(
                    //当用户在容器内部点击时,isAnimating变量的值将会改变
                    onTap: (){
                      setState(() {
                        isAnimating = !isAnimating;
                      });
                    },
                    child: AnimatedContainer(
                      duration: const Duration(seconds: 5),
                      height: isAnimating ? 200: 20,
                      width: isAnimating ? MediaQuery.of(context).size.width*0.8 :60,
                      curve: isAnimating ? Curves.bounceIn : Curves.bounceOut,
                      decoration: BoxDecoration(
                        color: isAnimating ?  Colors.green: Colors.blue,
                        borderRadius: isAnimating ? const BorderRadius.only(
                          topLeft: Radius.circular(30),
                          topRight: Radius.circular(30)
                        ) :const BorderRadius.all(Radius.circular(0)),
                        border: Border.all(
                          color: isAnimating ? Colors.orange :Colors.red,
                          width: isAnimating? 8 :2
                        ),
                      ),
                    ),
                  )
                ],
              )
            )
          ],
        ),
      )
    );
  }
}

效果:

slide2.gif