Flutter動畫合集1

anmy發表於2019-07-26

Flutter動畫合集


你可以在我的部落格看到這篇文章

Flutter 可以很方便的實現比較炫酷的動畫。

AnimatedContainer

在這個控制元件中可以方便的給它的width寬,height高,color背景色,padding內邊距,margin外邊距,transform變換,裝飾等,新增動畫,

使用它可以快速實現大部分的動畫效果,

寬高動畫

//標記動畫的狀態
 bool status = true;
//寬高的變數
 double _height = 100.0;
 double _width = 100.0;
//通過改變寬高的值,響應動畫處理,這個效果是控制元件的高度和寬度發生變化。如圖1
 void _animating() {
    setState(() {
      if (status) {
        _height = 100.0;
        _width = 100.0;
      } else {
        _height = 200.0;
        _width = 200.0;
      }
      status = !status;
    });
  }
//這是處理點選事件的widget
GestureDetector(
              //響應點選事件
              onTap: _animating,
              child: AnimatedContainer(
              //當height或者width的值發生變化時,自動進行動畫
                height: animationHeight,
                width: animationWidth,
                color: Colors.amber,
                duration: Duration(milliseconds: 300),
                child: Container(),
              ),
            ),
複製程式碼

圖1:響應寬高變化的動畫

顏色動畫

//背景顏色的變化
Color _color = Colors.amber;
void _animating() {
    setState(() {
    //直接改變顏色
      if (status) {
        _color = Colors.amber;
      } else {
        _color = Colors.blue;
      }
      status = !status;
    });
 }
  
     GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedContainer(
                  height: _height,
                  width: _width,
                  //加入了顏色的變化
                  color: _color,
                  duration: Duration(milliseconds: 300),
                  child: Container( ),
                ),
              ),
            ),
複製程式碼

注意顏色的變化。

圖2:顏色和寬高同時變化

padding 內邊距

void _animating() {
    setState(() {
      if (status) {
        _padingValue = 40.0;
      } else {
        _padingValue = 30.0;
      }
      status = !status;
    });
  }
 GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedContainer(
                  height: _height,
                  width: _width,
                  color: _color,
                  //加入了內邊距的變化
                  padding: EdgeInsets.all(_padingValue),
                  duration: Duration(milliseconds: 300),
                  child: Center(
                  //同時為了更好觀察內邊距的變化,我在內部加了一個寬度為80,顏色白色的小部件。注意觀察它的寬度變化
                    child: Container(
                      width: 80,
                      color: Colors.white,
                      child: Text("內部"),
                    ),
                  ),
                ),
              ),
            ),
複製程式碼

可以觀察到由於padding的變化,內部的寬度也發生了變化。

圖三:內邊距的變化

margin外邊距

 void _animating() {
    setState(() {
      if (status) {
        _marginValue = 0.0;
      } else {
        _marginValue = 30.0;
      }
      status = !status;
    });
  }
GestureDetector(
              onTap: _animating,
              child: Center(
              //為了觀察margin的變化,我在AnimatedContainer上下各加了widget,觀察他們之間的距離
                child: Column(
                  children: <Widget>[
                    Text("上"),
                    AnimatedContainer(
                      height: _height,
                      width: _width,
                      color: _color,
                      margin: EdgeInsets.all(_marginValue),
                      padding: EdgeInsets.all(_padingValue),
                      duration: Duration(milliseconds: 300),
                      child: Center(
                        child: Container(
                          width: 80,
                          color: Colors.white,
                          child: Text("內部"),
                        ),
                      ),
                    ),
                    Text("下"),
                  ],
                ),
              ),
            ),
複製程式碼

圖四:外邊距的變化

子控制元件對齊

注意這個屬性是作用在了子widget上

  void _animating() {
    setState(() {
      if (status) {
      //中間對齊
        _alignment = Alignment.center;
      } else {
      //底部右側
        _alignment = Alignment.bottomRight;
      }
      status = !status;
    });
  }
 GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedContainer(
                //控制內部的子控制元件的對齊方式
                  alignment: _alignment,
                  height: 300,
                  width: 300,
                  color: _color,
                  duration: Duration(milliseconds: 500),
                  child: Container(
                    width: 80,
                    color: Colors.white,
                    child: Text("內部"),
                  ),
                ),
              ),
            ),
            
複製程式碼

內部的子控制元件由中間移動到右下角

AnimatedContainer_color_aligment

transform 變換

這個主要是用到了矩陣變換,比如移動位置,放大,縮小 等操作。這些操作也有專門的widget,以後會寫出來。

void _animating() {
    setState(() {
      if (status) {
        _matrix4 = Matrix4.translationValues(0, 0, 0);
      } else {
        _matrix4 = Matrix4.translationValues(20, 50, 0);
      }
      status = !status;
    });
  }
 GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedContainer(
                  height: 150,
                  width: 150,
                  color: _color,
                  transform: _matrix4,
                  duration: Duration(milliseconds: 500),
                  child: Center(
                    child: Container(
                      width: 50,
                      height: 50,
                      color: Colors.deepOrange,
                    ),
                  ),
                ),
              ),
            ),
複製程式碼

這裡展示了位移的變化

AnimatedContainer_color_transfrom

但是使用transform進行變換的動畫操作還是有一定侷限的,比如旋轉操作無法指定旋轉的中心點,如果像實現這個操作還是得依靠AnimatedBuilder.

decoration 裝飾,比如背景色color(注意不能和外部的color同時設定,會報錯),邊框,等

GestureDetector(
              onTap: _animating,
              child: Center(
                child: AnimatedContainer(
                  height: 150,
                  width: 150,
                  //裝飾器
                  decoration: BoxDecoration(
		     //背景色也可以在這裡進行修改
                      color: _color,
                      //邊框的顏色和邊框寬度變化
                      border: Border.all(
                          color: status ? Colors.cyanAccent : Colors.black,
                          width: status ? 20 : 10)),
                  duration: Duration(milliseconds: 500),
                  child: Center(
                    child: Container(
                      width: 50,
                      height: 50,
                      color: Colors.deepOrange,
                    ),
                  ),
                ),
              ),
            )
複製程式碼

AnimatedContainer_decoration

相關文章