Flutter - 內置動畫 API

Flutter 內置動畫

上面的那些通常用起來不是很方便,即使是 AnimatedBuilder 仍是要指定參與動畫變化的 widget 屬性,爲了進一步方便咱們,官方在 AnimatedWidget 的基礎上封裝了下面這些內置動畫庫,就是 android 中的那些,固然更多一些:android

  • SlideTransition - 自身倍數位移動畫
  • AlignTransition - 沒找到資料
  • PositionedTransition - 縮放動畫,限定父佈局只能是 stack
  • FadeTransition - 透明度動畫
  • ScaleTransition - 縮放動畫,這個是 android 中的那種縮放動畫,能夠指定中心點
  • SizeTransition - 寬高動畫,限制是每次只能執行一個維度的動畫,寬和高一塊兒不行,那就是縮放動畫了
  • RotationTransition - 旋轉動畫,特色是其數值是 0-1 之間的,旋轉90度 = 0.25

這些 transition 的特色就是,用一個參數接受 animation 動畫,child 寫 widgetide


FadeTransition

FadeTransition 是透明度動畫,參數就是一個 opacity 指定動畫,child 寫 widget 就沒了佈局

animationController = AnimationController(
  duration: Duration(milliseconds: 300),
  vsync: this,
);

animation = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut);
animation = Tween(begin: 0.0, end: 1.0).animate(animationController);
複製代碼
Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          FadeTransition(
            opacity: animation,
            child: Container(
              margin: EdgeInsets.only(bottom: 20),
              width: 300,
              height: 300,
              color: Colors.blueAccent,
            ),
          ),
          RaisedButton(
            child: Text("放大"),
            onPressed: () {
              animationController?.forward();
            },
          ),
        ],
      ),
    );
  }
}
複製代碼

SlideTransition

SlideTransition 位移動畫,使用 offset 來承載x,y軸數據。須要注意的是 Offset(0.0, 0.0) 中的數值都是 倍數,也就是說 SlideTransition 只支持按 widget 自己長寬的倍數位移,不支持具體的數值的位移操做動畫

void initState() {
    super.initState();

    animationController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this,
    );

    animation = Tween(begin: Offset(0.0, 0.0), end: Offset(1.0, 1.0))
        .animate(animationController);
  }
複製代碼
Widget build(BuildContext context) {
    return Center(
      child: Column(
        mainAxisAlignment: MainAxisAlignment.center,
        children: <Widget>[
          SlideTransition(
            position: animation,
            child: Container(
              margin: EdgeInsets.only(bottom: 20),
              width: 100,
              height: 100,
              color: Colors.blueAccent,
            ),
          ),
          RaisedButton(
            child: Text("放大"),
            onPressed: () {
              animationController?.forward();
            },
          ),
        ],
      ),
    );
  }
複製代碼

PositionedTransition

PositionedTransition 縮放動畫,必須在 stack 中使用,其縮放數值使用 RelativeRect 包裹,先後變化的是距 stack 父佈局左上右下4個角的距離:ui

animation = RelativeRectTween(
            begin: RelativeRect.fromLTRB(0, 0, 0, 0),
            end: RelativeRect.fromLTRB(50, 200, 50, 200))
        .animate(animationController);
複製代碼

你們看個圖: this

基本上就是這個思路了,限制有一些,下面是例子代碼,不是上面 gif 的代碼:spa

Animation<RelativeRect> animation;
  AnimationController animationController;
  CurvedAnimation curve;

  void initState() {
    super.initState();

    animationController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this,
    );

    curve = CurvedAnimation(parent: animationController, curve: Curves.bounceInOut);
    
    animation = RelativeRectTween(
            begin: RelativeRect.fromLTRB(0, 0, 0, 0),
            end: RelativeRect.fromLTRB(50, 200, 50, 200))
        .animate(curve);
  }
複製代碼
Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          PositionedTransition(
            rect: animation,
            child: Container(
              width: 300,
              height: 300,
              color: Colors.blueAccent,
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
複製代碼

最後你們注意啊,RelativeRectTween begin 的數值能影響 widget 初始顯示時的寬高大小code


ScaleTransition

ScaleTransition 這纔是傳統的縮放動畫,使用 alignment: Alignment.topLeft 指定縮放中心點cdn

Animation<double> animation;
  AnimationController animationController;
  CurvedAnimation curve;

  @override
  void initState() {
    super.initState();

    animationController = AnimationController(
      duration: Duration(milliseconds: 300),
      vsync: this,
    );

    curve =
        CurvedAnimation(parent: animationController, curve: Curves.bounceInOut);
    animation = Tween(
      begin: 1.0,
      end: 0.3,
    ).animate(curve);
  }

複製代碼
Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          ScaleTransition(
            alignment: Alignment.topLeft,
            scale: animation,
            child: Container(
              width: 300,
              height: 300,
              color: Colors.blueAccent,
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
複製代碼

SizeTransition

SizeTransition 寬高動畫,限制是每次只能設定一個維度,不能寬和高一塊兒,優勢是寬高的變化不會引發內容的變形blog

axis: Axis.horizontal 就是指定動畫做用與寬仍是高

Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          SizeTransition(
            axis: Axis.horizontal,
            sizeFactor: animation,
            child: Container(
              color: Colors.blueAccent,
              child: Icon(Icons.access_alarm, size: 300),
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
複製代碼

RotationTransition

RotationTransition 旋轉動畫,特色是其數值是 0-1 之間的,旋轉90度 = 0.25,依然能夠設置原點

animation = Tween(
  begin: 0.0,
  end: 0.25,
).animate(curve);
複製代碼
Widget build(BuildContext context) {
    return Center(
      child: Stack(
        children: <Widget>[
          RotationTransition(
            turns: animation,
            alignment: Alignment.center,
            child: Container(
              color: Colors.blueAccent,
              child: Icon(Icons.access_alarm, size: 300),
            ),
          ),
          Positioned(
            top: 20,
            left: 20,
            child: RaisedButton(
              child: Text("放大"),
              onPressed: () {
                animationController?.forward();
              },
            ),
          ),
        ],
      ),
    );
  }
複製代碼
相關文章
相關標籤/搜索