🎢

AnimatedContainer 俺的Widget of the Week #1

2021/07/18に公開

1. はじめに

Flutterは、モバイル、ウェブ、デスクトップ、組み込み機器向けに、単一のコードベースからネイティブにコンパイルされた美しいアプリケーションを構築するためのGoogleのUIツールキットです(Flutter公式)。

私を含め忘れがちなのが、「美しいアプリケーション」という点です。Flutterは美しいアプリケーションを作るためのGoogleのUIツールキットなのです。

また、アニメーションはビジネス的観点からも非常に重要だと言えます。
丁寧に設計されたアニメーションは、UIをより直感的にし、見た目を洗練させ、UXを向上させます(Introduction to animations)。UXの向上はアプリの利用率に直結し、会社の売り上げに対して非常に大きな役割を果たすでしょう。

2. Flutterのアニメーション

Flutterのアニメーションは大きく2つに分類できます。

Explicit Animation

  • さまざまなコントロールが可能
  • 実装が複雑

Implicit Animation

  • コントロールできる範囲が狭い
  • 実装が簡単

今回ご紹介する、AnimatedContainerはImplicit Animationに分類されます。
下の図を見ていただければ一目瞭然だと思います。もっとも実装が簡単です。

How to Choose Which Flutter Animation Widget is Right for You?の意訳

2つのアニメーションの違いについてより深く知りたい場合は、Flutterチームの 「How to Choose Which Flutter Animation Widget is Right for You?」をご覧ください。

3. 実装

AnimatedContainerを実装します。 AnimatedContainerは時間の経過とともに値が変わっていくアニメーション版Containerウィジェットです(AnimatedContainer class)。

完成版

完成版は以下の通りです。FloatingActionButtonを押すたびに背景がアニメーションで変わっていきます。(読み込みに少し時間がかかります。数秒お待ちください。)

実行環境

  • Flutter stable v2.2.3

Stateful Widget

BackgroundChangerPageというStateful Widgetを作成します。
色のみ変化するので、状態変数は_colorを置いておきます。

class BackgroundChangerPage extends StatefulWidget {
  const BackgroundChangerPage({Key? key}) : super(key: key);

  
  _BackgroundChangerPageState createState() => _BackgroundChangerPageState();
}

class _BackgroundChangerPageState extends State<BackgroundChangerPage> {
  
  // 状態変数。この値が変化していく。
  Color _color = Colors.transparent;

  
  Widget build(BuildContext context) {
    return Scaffold();
  }
}

AnimatedContainer

ScaffoldのbodyパラメーターにはAnimatedContainerを渡します。
curveパラメータに渡せるオブジェクトは、Curves classで確認できます。

AnimatedContainer(
        color: _color,
	// 新しい状態へ遷移するまでの時間。今回は1秒に設定。
        duration: Duration(seconds: 1),
	// アニメーションの種類。今回はfastOutSlowInを使用。
        curve: Curves.fastOutSlowIn,
      ),

状態の変更

FloatingActionButton

FloatingActionButton(
        onPressed: () => changeColor(),
        child: Icon(Icons.refresh),
      ),

FloatingActionButtonをタップすると、_colorの状態がランダムで変更されるようにしました。
Randomクラスを使用し、RGB値をランダムに生成しています。

  void changeColor() {
    setState(() {
      final random = Random();
      _color = Color.fromRGBO(
        random.nextInt(256),
        random.nextInt(256),
        random.nextInt(256),
        1,
      );
    });
  }

比較

比較できるように、アニメーションある場合とない場合を貼っておきます。

アニメーションなし アニメーションあり

コードは以下に置いておきます。ご自由にお使いください。
https://github.com/mafreud/animated_container_sample

参考文献

https://flutter.dev/docs/development/ui/animations
https://medium.com/flutter-jp/implicit-animation-b9d4b7358c28
https://api.flutter.dev/flutter/widgets/AnimatedContainer-class.html

Discussion