Flutter動畫 --- 平移/旋轉(zhuǎn)/縮放/漸變

PS: Flutter中文網(wǎng)提供的動畫組件真心太多了,貌似有25種,看著裂開了。。。太多了,用的時候反而不好選擇了,感覺只要用自己最熟悉的能實現(xiàn)效果就是最好的。。。
再復(fù)雜的動畫也是由簡單動畫組成的,還是熟悉一下4種基本動畫效果吧。。。

  • 動畫核心類簡介

在Flutter中Widget動畫的核心類有下面這些:
Animation:動畫庫中的一個核心類,它生成指導(dǎo)動畫的值;
CurvedAnimation:將動畫過程抽象為一個非線性曲線;
AnimationController:用來管理管理動畫,常用的方法有forward():啟動動畫;reverse({double from}:倒放動畫;reset():重置動畫,將其設(shè)置到動畫的開始位置;stop({ bool canceled = true }):停止動畫。
Tween:AnimationController對象的范圍從0.0到1.0。如果您需要不同的范圍或不同的數(shù)據(jù)類型,則可以使用Tween來配置動畫以生成不同的范圍或數(shù)據(jù)類型的值。

  • 平移動畫:SlideTransition
    • 先看下構(gòu)造方法如下圖,必要參數(shù)是 Animation<Offset> position


      image.png
  • 示例代碼:

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

///
/// 平移動畫
///
class TransAnimationTest extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => TransAnimationTestState();
}

class TransAnimationTestState extends State<TransAnimationTest>
    with TickerProviderStateMixin {
  AnimationController controller;
  Animation<Offset> animation;

  @override
  void initState() {
    super.initState();
    controller =
        AnimationController(duration: Duration(milliseconds: 2000), vsync: this)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    animation = Tween(
            begin: Offset.zero,
            end: Offset((MediaQuery.of(context).size.width - 100) / 100, 1))
        .animate(controller);
    return Scaffold(
      appBar: AppBar(title: Text("平移動畫")),
      body: Container(
        child: SlideTransition(
          position: animation,
          child: Container(
            margin: EdgeInsets.fromLTRB(0, 20, 0, 0),
            width: 100,
            height: 100,
            color: Colors.red,
          ),
        ),
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}

平移動畫.gif
  • 旋轉(zhuǎn)動畫: RotationTransition
    • 構(gòu)造函數(shù)需要:Animation<double> turns


      image.png
    • 示例代碼

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

///
/// 旋轉(zhuǎn)動畫
///
class RotateAnimationTest extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => RotateAnimationTestState();
}

class RotateAnimationTestState extends State<RotateAnimationTest>
    with TickerProviderStateMixin {
  AnimationController controller;
  Animation animation;

  @override
  void initState() {
    super.initState();
    controller =
    AnimationController(duration: Duration(milliseconds: 2000), vsync: this)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          controller.reverse();
        } else if (status == AnimationStatus.dismissed) {
          controller.forward();
        }
      });
    animation = Tween<double>(begin: 0, end: 0.5).animate(controller);
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("旋轉(zhuǎn)動畫")),
      body: ClipOval(
        child: RotationTransition(
          turns: animation,
          child: Center(
            child: Container(
              width: 100,
              height: 100,
              alignment: Alignment.center,
              color: Colors.red,
              child: Text("旋轉(zhuǎn)起來"),
            ),
          )
        ),
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}
旋轉(zhuǎn)動畫.gif
  • 縮放動畫:ScaleTransition
    • 構(gòu)造函數(shù)必要參數(shù): Animation<double> scale


      image.png
    • 示例代碼

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

///
/// 縮放動畫
///
class ScaleAnimationTest extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => ScaleAnimationTestState();
}

class ScaleAnimationTestState extends State<ScaleAnimationTest>
    with TickerProviderStateMixin {
  AnimationController controller;
  Animation<double> animation;

  @override
  void initState() {
    super.initState();
    controller =
        AnimationController(duration: Duration(milliseconds: 2000), vsync: this)
          ..addStatusListener((status) {
            if (status == AnimationStatus.completed) {
              controller.reverse();
            } else if (status == AnimationStatus.dismissed) {
              controller.forward();
            }
          });
    controller.forward();
    animation = Tween<double>(begin: 0.5, end: 1).animate(controller);
  }

  @override
  Widget build(BuildContext context) {

    return Scaffold(
      appBar: AppBar(title: Text("縮放動畫")),
      body: Container(
        child: ScaleTransition(
          scale: animation,
          child: Center(
            child: Container(
              width: 100,
              height: 100,
              color: Colors.red,
            ),
          )
        ),
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}
縮放動畫.gif
  • 漸變動畫:FadeTransition
    • 構(gòu)造函數(shù)必要參數(shù): Animation<double> opacity


      image.png
    • 示例代碼

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';

///
/// 漸變動畫
///
class FadeAnimationTest extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => FadeAnimationTestState();
}

class FadeAnimationTestState extends State<FadeAnimationTest>
    with TickerProviderStateMixin {
  AnimationController controller;
  Animation animation;

  @override
  void initState() {
    super.initState();
    controller =
    AnimationController(duration: Duration(milliseconds: 2000), vsync: this)
      ..addStatusListener((status) {
        if (status == AnimationStatus.completed) {
          controller.reverse();
        } else if (status == AnimationStatus.dismissed) {
          controller.forward();
        }
      });
    animation = Tween<double>(begin: 0.25, end: 1).animate(controller);
    controller.forward();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("漸變動畫")),
      body: ClipOval(
        child: FadeTransition(opacity: animation,
          child: Center(
            child: Container(
              width: 100,
              height: 100,
              alignment: Alignment.center,
              color: Colors.red,
            ),
          )
        ),
      ),
    );
  }

  @override
  void dispose() {
    controller.dispose();
    super.dispose();
  }
}
漸變動畫.gif
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容