首頁 > 軟體

Android Flutter製作交錯動畫的範例程式碼

2022-06-28 14:03:38

前言

之前一篇我們講了 Flutter組合動畫實現的方式 —— 交錯動畫。藉助 GIF 和繪圖技巧是可以做到類似 GIF 那種效果的。本篇我們來一個應用範例,我們讓輪子在草地捲動著前進,而且還能粘上“綠色的草”,執行效果如下動畫所示。

動畫解析

上面實現的效果實際上由三個動畫組成:

  • 輪子前進的動畫
  • 輪子捲動
  • 輪子的邊緣顏色漸變(由黑色變成綠色)

這三個動畫是同時進行的,因此需要使用到交錯動畫,即使用一個 AnimationController來控制三個 Tween 物件實現上述的動畫組合。

編碼實現

首先是輪子元件的定義,為了讓輪子轉動的效果能夠看到,我們給輪子填充了線性的漸變色,然後輪子的尺寸、旋轉速度(time)和邊框顏色由上級元件來控制。整個實現很簡單,就是一個加了裝飾的 Container 而已。

class Wheel extends StatelessWidget {
  final double size;
  final Color color;
  final double time;
  const Wheel({
    Key? key,
    required this.size,
    required this.time,
    required this.color,
  }) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Container(
      width: size,
      height: size,
      transform: Matrix4.identity()..rotateZ(2 * pi * time),
      transformAlignment: Alignment.center,
      decoration: BoxDecoration(
        border: Border.all(color: color, width: 10.0),
        borderRadius: BorderRadius.circular(size / 2),
        gradient: LinearGradient(
          colors: [
            Colors.white,
            Colors.orange[100]!,
            Colors.orange[400]!,
          ],
        ),
      ),
    );
  }
}

然後是整個頁面佈局,整個頁面佈局其實就是一個 Stack,然後底部是綠色的 Container再加兩個輪子,都是使用 Positioned 來確定各自的位置。然後就是通過受控的Tween 物件控制輪子的旋轉速度,輪子外邊沿顏色和移動的距離,程式碼如下,其中輪子移動距離通過控制邊距實現。

Widget build(BuildContext context) {
  final bottomHeight = MediaQuery.of(context).size.height / 3;
  return Scaffold(
    appBar: AppBar(
      title: const Text('交錯動畫'),
    ),
    body: Stack(children: [
      Positioned(
        child: Container(
          width: double.infinity,
          height: bottomHeight,
          color: Colors.green[400],
        ),
        bottom: 0,
        left: 0,
        right: 0,
      ),
      Positioned(
          child: Wheel(
            size: wheelSize,
            color: _color.value!,
            time: _time.value,
          ),
          left: _offset.value * MediaQuery.of(context).size.width,
          bottom: bottomHeight),
      Positioned(
          child: Wheel(
            size: wheelSize,
            color: _color.value!,
            time: -_time.value,
          ),
          right: _offset.value * MediaQuery.of(context).size.width,
          bottom: bottomHeight)
    ]),
    floatingActionButton: FloatingActionButton(
      child: Icon(Icons.play_arrow),
      onPressed: () {
        if (_controller.isCompleted) {
          _controller.reverse();
        } else if (!_controller.isAnimating) {
          _controller.forward();
        }
      },
    ),
  );
}

最後就是構建受AnimationController 控制的 Tween 物件了,這個在Flutter 做出 GIF 動畫效果已經介紹過了,程式碼如下:

late AnimationController _controller;
late Animation<double> _time;
late Animation<double> _offset;
late Animation<Color?> _color;

final wheelSize = 80.0;

@override
void initState() {
  _controller =
      AnimationController(duration: Duration(seconds: 4), vsync: this)
        ..addListener(() {
          setState(() {});
        });

  _time = Tween<double>(begin: 0, end: 8.0).animate(
    CurvedAnimation(
      parent: _controller,
      curve: Interval(
        0.0,
        1.0,
        curve: Curves.linear,
      ),
    ),
  );
  _offset = Tween<double>(begin: 0, end: 1.0).animate(
    CurvedAnimation(
      parent: _controller,
      curve: Interval(
        0.0,
        1.0,
        curve: Curves.easeInCubic,
      ),
    ),
  );
  _color = ColorTween(begin: Colors.black87, end: Colors.green).animate(
    CurvedAnimation(
      parent: _controller,
      curve: Interval(
        0.0,
        0.8,
        curve: Curves.easeIn,
      ),
    ),
  );
  super.initState();
}

就這樣,一對奔向對方的輪子動畫效果就完成了!

總結

交錯動畫實際上可以實現非常有創意的動效,只是這樣會需要很高的繪圖技巧,比如使用 CustomPaint 來做。接下來的幾篇我們來介紹一下 CustomPaint相關的內容。

以上就是Android Flutter製作交錯動畫的範例程式碼的詳細內容,更多關於Android Flutter交錯動畫的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com