首页 > 建站教程 > APP开发,混合APP >  Flutter笔记70:BorderRadiusTween边框圆角补间动画正文

Flutter笔记70:BorderRadiusTween边框圆角补间动画

通过BorderRadiusTween和Tween共用一个AnimationController,即叠加多个动画,实现类似遮罩的效果,Tween动画负责宽高,BorderRadiusTween负责边框圆角动画:

main.dart:
import 'package:flutter/material.dart';
import 'mask.dart';

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

//通过BorderRadiusTween和Tween共用一个AnimationController,即叠加多个动画,实现类似遮罩的效果,Tween动画负责宽高,BorderRadiusTween负责边框圆角动画

class MyApp extends StatelessWidget {
  const MyApp({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      child: MaterialApp(
        title: 'Flutter边框补间动画BorderRadiusTween实现遮罩动画',
        theme: ThemeData(
          primarySwatch: Colors.blue
        ),
        debugShowCheckedModeBanner: false,
        home: AnimateDemo(),
      ),
    );
  }
}

class AnimateDemo extends StatelessWidget{
  @override
  Widget build(BuildContext context) {

    List<Widget> list = [
      MaskAnimation()
    ];

    return Scaffold(
      appBar: AppBar(
        title: Text('动画示例'),
      ),
      body: ListView(
        children: list.map((widget){
          return ListTile(
            title: Text(widget.toString()),
            onTap: (){
              Navigator.of(context).push(MaterialPageRoute(builder: (context)=>widget));
            },
          );
        }).toList(),
      ),
    );
  }
}
mask.dart:
import 'package:flutter/material.dart';

class MaskAnimation extends StatefulWidget{
  MaskAnimation({Key key}) : super(key:key);

  _MaskAnimationState createState() => _MaskAnimationState();
}

//混入 SingleTickerProviderStateMixin 是为了在不显示当前页面时,动画停止,节约资源
class _MaskAnimationState extends State<MaskAnimation> with SingleTickerProviderStateMixin{
  AnimationController _controller;
  Animation<double> transitionTween;
  Animation<BorderRadius> borderRadius;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(duration:Duration(seconds: 10), vsync: this)
                  ..addStatusListener((status) {
                    if(status == AnimationStatus.completed){
                      Navigator.pop(context);
                    }
                  });

    transitionTween = Tween<double>(begin: 50, end: 200).animate(
      //非线性动画
      CurvedAnimation(
        parent: _controller,
        curve: Curves.ease
      )
    );

    //边框弧度补间动画
    borderRadius = BorderRadiusTween(begin: BorderRadius.circular(75.0), end: BorderRadius.circular(0.0)).animate(
      //非线性动画
      CurvedAnimation(
        parent: _controller,
        curve: Curves.ease
      )
    );
    _controller.forward();
  }

  //销毁动画
  @override
  void dispose() {
    super.dispose();
    _controller.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return AnimatedBuilder(
      animation: _controller,
      builder: (context,child){
        return Scaffold(
          appBar: AppBar(
            title: Text('遮罩动画'),
          ),
          body: Center(
            child: Stack(
              children: [
                Center(
                  child: Container(
                    width: 200.0,
                    height: 200.0,
                    color: Colors.black12,
                  ),
                ),
                Center(
                  child: Container(
                    alignment: Alignment.bottomCenter,
                    width: transitionTween.value,
                    height: transitionTween.value,
                    decoration: BoxDecoration(
                      color: Colors.black12,
                      borderRadius: borderRadius.value
                    ),
                    color: Colors.black12,
                  ),
                ),
              ],
            ),
          ),
        );
      }
    );
  }
}