flutter系列之:做一個修改元件屬性的動畫

2023-05-09 15:00:24

簡介

什麼是動畫呢?動畫實際上就是不同的圖片連續起來形成的。flutter為我們提供了一個AnimationController來對動畫進行詳盡的控制,不過直接是用AnimationController是比較複雜的,如果只是對一個widget的屬性進行修改,可以做成動畫嗎?

答案是肯定的,一起來看看吧。

flutter中的動畫widget

如果你只是希望動畫展示widget的屬性的變化,比如比如長度,高度,寬度或者顏色等進行動態變化,那麼可以直接使用flutter提供的AnimatedContainer。

先來看下AnimatedContainer的定義:

class AnimatedContainer extends ImplicitlyAnimatedWidget

AnimatedContainer繼承自ImplicitlyAnimatedWidget,什麼是ImplicitlyAnimatedWidget呢?翻譯過來就是隱式的動畫widget。

這個widget會自動根據widget屬性的變化生成對應的動畫。在使用上非常的簡單。

AnimatedContainers使用舉例

AnimatedContainer是一個container,所以它可以包含child屬性,但是AnimatedContainer的動畫只是針對容器本身來說的,動畫並不會應用到它的child中。

所以為了展示widget本身的變化,我們可以給widget設定一個BoxDecoration,設定它的顏色跟borderRadius。

如下所示:

body: Center(
          child: AnimatedContainer(
            width: 200,
            height: 200,
            decoration: BoxDecoration(
              color: Colors.blue,
              borderRadius: BorderRadius.circular(10),
            ),
            duration: const Duration(seconds: 1),
            curve: Curves.easeInBack,
          ),
        )

上面的程式碼會在介面上展示一個長度和寬度都等於200的Container,它的背景是blue,還有一個圓形的borderRadius。

並且我們定義了動畫的duration和變動曲線的方式。

接下來我們只需要在setState方法中對AnimatedContainer中的屬性進行變化,就會自動觸發動畫效果。

為了實現這個動畫的功能,我們需要把width,height等屬性用動態變數儲存起來,這樣才可以在setState的時候對屬性進行變動。

我們將這些屬性放在一個StatefulWidget的State中:

  double _width = 100;
  double _height = 100;
  Color _color = Colors.blue;
  BorderRadiusGeometry _borderRadius = BorderRadius.circular(10);

這樣我們在build方法中使用上面定義的屬性:

        body: Center(
          child: AnimatedContainer(
            width: _width,
            height: _height,
            decoration: BoxDecoration(
              color: _color,
              borderRadius: _borderRadius,
            ),
            duration: const Duration(seconds: 1),
            curve: Curves.easeInBack,
          ),
        )

然後在floatingActionButton的onPressed中修改這些屬性,從而實現widget屬性變化的動畫功能:

floatingActionButton: FloatingActionButton(
          onPressed: () {
            setState(() {
              final random = Random();

              _width = random.nextInt(200).toDouble();
              _height = random.nextInt(200).toDouble();

              _color = Color.fromRGBO(
                random.nextInt(256),
                random.nextInt(256),
                random.nextInt(256),
                1,
              );

              _borderRadius =
                  BorderRadius.circular(random.nextInt(10).toDouble());
            });
          }

最後實現的效果如下:

總結

如果你只是希望使用簡單的widget動畫,那麼AnimatedContainer可能是你最好的選擇。

本文的例子:https://github.com/ddean2009/learn-flutter.git