Flutter动画widget合集(2)

Flutter动画widget合集2

包含的比较多,但是都比较零散,有以下几个部分。
AnimatedCrossFade
AnimatedOpacity
AnimatedPadding
AnimatedSize
AnimatedAlign
AnimatedSwitcher
AnimatedPositioned
AnimatedIcon

AnimatedCrossFade

这个控件的效果是在两个控件切换时进行显示上的过渡。
控件内需要有两个widget,一个firstChild,一个secondChild,通过crossFadeState控制显示哪个child,并在切换时进行渐隐渐显的效果。

 void _animating() {
    setState(() {
    //状态切换
      status = !status;
    });
}
 GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedCrossFade(
                  firstChild: Container(
                    width: 200,
                    height: 200,
                    child: Text(
                      "第一个子widget",
                      style: TextStyle(
                          backgroundColor: Colors.deepOrange, fontSize: 30),
                    ),
                  ),
                  secondChild: Text(
                    "第二个子widget",
                    style: TextStyle(
                        backgroundColor: Colors.blueAccent, fontSize: 30),
                  ),
                  //用于控制显示哪个widget
                  crossFadeState: status
                      ? CrossFadeState.showFirst
                      : CrossFadeState.showSecond,
                  duration: Duration(milliseconds: 500),
                ),
              ),
            ),

两个childWidget在切换时的过渡效果,那些辅助线是我开启了Debug paint才显示的,可以忽略掉。

AnimatedCrossFade

AnimatedOpacity

控件透明度动画, 在opacity的值发生改后自动对childWidget进行透明度动画。

void _animating() {
    setState(() {
    //状态切换
      status = !status;
    });
}
 GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedOpacity(
                    child: Container(
                      width: 200,
                      height: 200,
                      color: Colors.deepOrange,
                      child: Text(
                        "透明度动画演示",
                        style: TextStyle(fontSize: 40.0),
                      ),
                    ),
                    //在opacity的值发生改后自动进行透明度动画
                    opacity: status ? 1.0 : 0.0,
                    duration: Duration(milliseconds: 500)),
              ),
            ),

AnimatedOpacity内childWidget的透明度发生了改变

AnimatedOpacity

AnimatedPadding

可以改变子控件的padding的动画,和对AnimateContainer的padding修改时的动画效果一样

void _animating() {
    setState(() {
    //状态切换
      status = !status;
    });
}
  GestureDetector(
              onTap: _animating,
              child: Center(
                child: Container(
                //外部我用了紫色背景
                  color: Colors.deepPurpleAccent,
                  child: AnimatedPadding(
                  //改变的是Text的padding
                    child: Text(
                      "padding动画演示",
                      style: TextStyle(fontSize: 40.0),
                    ),
                    duration: Duration(milliseconds: 500),
                    padding: EdgeInsets.all(status ? 50 : 0.0),
                  ),
                ),
              ),
            ),

可以看到因为padding的改变,外层的Container被撑大了

AnimatedPadding

AnimatedSize

这个控件的用意是,当子控件的大小发生变化时会有一个动画。不过目前(2019.7.25)这个控件显示的是有问题的。

如果你想使用的话,推荐Animatecontainer的方式进行控件大小的改变

  GestureDetector(
              onTap: _animating,
              child: AnimatedSize(
                child: Container(
                  color: Colors.deepPurpleAccent,
                  //对高度进行了演示。
                  height: status ? 60 : 150,
                  child: Text(
                    "AnimatedSize动画演示",
                    style: TextStyle(fontSize: 40.0),
                  ),
                ),
                duration: Duration(milliseconds: 500),
                //注意这个,要在state里width TickerProviderStateMixin
                vsync: this,
              ),
            ),

可以看到,变大时候时候是有动画的,但是变小的时候,没有期望中的动画。更多信息可以在issue中看到。
https://github.com/flutter/flutter/issues/21384

AnimatedSize

AnimatedAlign

对控件的对齐方式进行动画

GestureDetector(
          onTap: _animating,
          child: AnimatedAlign(
          //中心对齐和中心靠右对齐
            alignment: status ? Alignment.center : Alignment.centerRight,
            duration: Duration(milliseconds: 500),
            child: Container(
              color: Colors.deepPurpleAccent,
              child: Text(
                "AnimatedAlign动画演示",
                style: TextStyle(fontSize: 40.0),
              ),
            ),
          ),
        ),
AnimatedAlign

AnimatedSwitcher

 void _animating() {
    setState(() {
      switchSize++;
      status = !status;
    });
  }
 GestureDetector(
          onTap: _animating,
          child: AnimatedSwitcher(
            //进行自定义的切换动画
            transitionBuilder: (Widget child, Animation<double> animation) {
              return ScaleTransition(child: child, scale: animation);
            },
            //如果childWidget的key发生的变动,就会触发动画,这里是Text和Container的切换,二者的key自然是不同的,如果同时Text,则要注意给Text设置不同的key
            child: status
                ? Text(
                    "AnimatedSwitcher动画演示${switchSize}",
                    style: TextStyle(fontSize: 40.0),
                  )
                : Container(
                    width: 50,
                    height: 50,
                    color: Colors.deepOrange,
                  ),
            duration: Duration(milliseconds: 500),
          ),
        )

这个是在Text和Container切换的动画,也即上面代码的效果
AnimatedSwitcher3

这个是在不同的Text直接切换的动画,注意我设置了不同的Text的值。

AnimatedSwitcher2

AnimatedPositioned

可以对控件的位置进行动画。但是有一些限制。

  1. 父Widget必须是Stack
  2. 在水平维度上有left,right,width,这三者必须有一个值为null
  3. 在垂直维度上有top,bottom,height,这三者必须有一个值为null、
    同样的这个动画也可以用AnimateContainer来实现。
 GestureDetector(
          onTap: _animating,
          child: Stack(
            children: <Widget>[
              AnimatedPositioned(
                top: status ? 50 : 100,
                height: status ? 50 : 100,
                left: status ? 50 : 100,
                child: Container(
                  color: Colors.deepPurpleAccent,
                  child: Text(
                    "AnimatedPositioned动画演示${switchSize}",
                    style: TextStyle(fontSize: 30.0),
                  ),
                ),
                duration: Duration(milliseconds: 500),
              ),
            ],
          ),
        ),
AnimatedPositioned

AnimatedIcon

AnimatedIcon,动画图标

  @override
  void initState() {
    super.initState();
    _controller =
        //同样要使所在的State with TickerProviderStateMixin
        AnimationController(vsync: this, duration: Duration(milliseconds: 500));
  }
  void _animating() {
    setState(() {
      if (status) {
        _controller.forward();
      } else {
        _controller.reverse();
      }
      status = !status;
    });
  }

GestureDetector(
          onTap: _animating,
          child: Wrap(
            children: <Widget>[
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.arrow_menu,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.menu_arrow,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.close_menu,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.menu_close,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.home_menu,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.menu_home,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.list_view,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.view_list,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.ellipsis_search,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.search_ellipsis,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.add_event,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.event_add,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.pause_play,
                progress: _controller,
              ),
              AnimatedIcon(
                size: 100,
                icon: AnimatedIcons.play_pause,
                progress: _controller,
              ),
            ],
          ),
        ),

这里我把,所有官方的AnimatedIcon列出来的,这个实际上还是Path实现的。

AnimatedIcon