美文网首页工作生活
分页下标动画源码

分页下标动画源码

作者: twj小鱼儿 | 来源:发表于2019-07-04 19:30 被阅读0次

    直接引用 YJPvAnimationWidget()作为控件即可看效果。

    import 'package:flutter/material.dart';
    
    enum YJPvAnimationDirection {
      left,
      right,
    }
    
    class YJPvAnimationSharedModel {
      String action; //动画动作
      YJPvAnimationDirection direction; 
      YJPvAnimationSharedModel({this.action = 'wait', this.direction = YJPvAnimationDirection.right});
    }
    
    class YJPvAnimationSharedContext extends InheritedWidget{
    
      YJPvAnimationSharedModel model;
    
      YJPvAnimationSharedContext({
        Key key,
        @required this.model,
        @required Widget child,YJPvAnimationSharedModel
      }) : super(key: key, child: child);
    
      static YJPvAnimationSharedContext of(BuildContext context){
        return context.inheritFromWidgetOfExactType(YJPvAnimationSharedContext);
      }
    
      @override
      bool updateShouldNotify(YJPvAnimationSharedContext oldWidget) {
        // TODO: implement updateShouldNotify
        print('updateShouldNotify');
        return true;
      }
    
    }
    
    class YJPvAnimationWidget extends StatefulWidget {
      @override
      _YJPvAnimationWidgetState createState() => _YJPvAnimationWidgetState();
    }
    
    class _YJPvAnimationWidgetState extends State<YJPvAnimationWidget> {
    
      YJPvAnimationSharedModel model;
    
      @override
      void initState() {
        // TODO: implement initState
        model = new YJPvAnimationSharedModel();
        super.initState();
      }
    
      @override
      Widget build(BuildContext context) {
        return new YJPvAnimationSharedContext(
          model: model, 
          child: Container(
            color: Colors.grey,
            height: 60,
            width: double.infinity,
            child: Stack(      
              children: <Widget>[
                Positioned(
                  child: Container(   
                    color:Colors.yellow,
                    alignment: Alignment.center,
                    width: 100,
                    height: 10,
                    child: YJPvAnimationItemWidget(),
                  )
                ),
                Positioned(
                  left: 100,
                  top: 15,
                  child: RaisedButton(
                    child: Text('向右启动动画'),
                    onPressed: (){
                      setState(() {
                        model.action = 'restart';
                        model.direction = YJPvAnimationDirection.right;
                      });
                    },
                  ),
                ),
                Positioned(
                  left: 250,
                  top: 15,
                  child: RaisedButton(
                    child: Text('向左启动动画'),
                    onPressed: (){
                      setState(() {
                        model.action = 'restart';
                        model.direction = YJPvAnimationDirection.left;
                      });
                    },
                  ),
                ),
              ],
            ),
          )
        );
      }
    }
    
    class YJPvAnimationItemWidget extends StatefulWidget {
      @override
      _YJPvAnimationItemWidgetState createState() => _YJPvAnimationItemWidgetState();
    }
    
    class _YJPvAnimationItemWidgetState extends State<YJPvAnimationItemWidget> with TickerProviderStateMixin {
    
      Animation<Size> _widthUpAni;
      Animation<Size> _widthDownAni;
    
      AnimationController _controllerUp;
      AnimationController _controllerDown;
    
      bool _isWidthShrink; //是否正在收缩状态
      YJPvAnimationDirection _direction;
    
      static const double _minWidth = 10;
      static const double _maxWidth = 50;
    
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
        print('initState');
        _isWidthShrink = false;
        _direction = YJPvAnimationDirection.right;
        _initController();
        _initAni();
        _start();
      }
    
      Future _start() async{
        await _controllerUp.forward();
      }
    
      void _initController(){
        _controllerUp = AnimationController(
          duration: Duration(milliseconds: 500),
          vsync: this,
        );
        _controllerDown = AnimationController(
          duration: Duration(milliseconds: 500),
          vsync: this,
        );
      }
    
      void _initAni(){
        _widthUpAni = SizeTween(
          begin: Size.fromWidth(_minWidth),
          end: Size.fromWidth(_maxWidth),
        ).animate(
          CurvedAnimation(
            parent: _controllerUp,
            curve: Interval(0, 1, curve: Curves.fastOutSlowIn
            ),
          ),
        )
        ..addListener((){
          setState(() {});
        })
        ..addStatusListener((AnimationStatus status){
          print('--------------1');
          print(status);
          if (status == AnimationStatus.completed) {
            _isWidthShrink = true;
            _controllerDown.forward();
          }
        });
    
        _widthDownAni = SizeTween(
          begin: Size.fromWidth(_maxWidth),
          end: Size.fromWidth(_minWidth),
        ).animate(
          CurvedAnimation(
            parent: _controllerDown,
            curve: Interval(0, 1, curve: Curves.fastOutSlowIn
            ),
          ),
        )
        ..addListener((){
          setState(() {});
        })
        ..addStatusListener((AnimationStatus status){
          print('--------------2');
          print(status);
          if (_widthDownAni.status == AnimationStatus.completed ) {
            _isWidthShrink = false;
            _controllerUp.reset();
            _controllerDown.reset();
          }
        });
    
      }
    
      @override
      Widget build(BuildContext context) {
        
        //宽度变化
        double _width = _isWidthShrink ? _widthDownAni.value.width : _widthUpAni.value.width; 
        //margin变化
        double _margin = _isWidthShrink ? (_maxWidth -  10 + _maxWidth - _widthDownAni.value.width) : (_widthUpAni.value.width - 10);
    
        return Container(
          height: 10,
          decoration: BoxDecoration(
            color: Colors.blue,
            borderRadius: BorderRadius.all(Radius.circular(5)),
          ),
          width: _width,
          margin: _direction == YJPvAnimationDirection.left ? EdgeInsets.only(right: _margin) : EdgeInsets.only(left: _margin),
        );
      }
    
      @override
      void didChangeDependencies() {
        print('didChangeDependencies');
        // TODO: implement didChangeDependencies
        super.didChangeDependencies();
        final ctx = YJPvAnimationSharedContext.of(context);
        if (ctx.model.action == 'restart') {
          _direction = ctx.model.direction;
          _start();
        }
      }
    
      @override
      void didUpdateWidget(YJPvAnimationItemWidget oldWidget) {
        // TODO: implement didUpdateWidget
        super.didUpdateWidget(oldWidget);
        print('didUpdateWidget${oldWidget.runtimeType.hashCode}');
      }
    
      @override
      void dispose() {
        print('dispose');
        // TODO: implement dispose
        _controllerUp.dispose();
        super.dispose();
      }
    
    }
    
    

    相关文章

      网友评论

        本文标题:分页下标动画源码

        本文链接:https://www.haomeiwen.com/subject/xjhdhctx.html