【Flutter】ローディング中に使えるちょっとしたアニメーションの実装方法

こんにちは。株式会社Pentagonでアプリ開発をしているmamiです。

今回はFlutterでサーバへのリクエスト中など処理に時間がかかる時に、画面にローディングアニメーションを表示する方法について調べました。よく使われているのは、「CircularProgressIndicator」というウィジェットでくるくる回るインディケーターが表示されます。今回はくるくるインジケーターの部分を好きなアニメーションに変えて表示させる方法についてご紹介します。

【こんな人に読んで欲しい】

  • ユーザーエクスペリエンス(UX)を向上させたい方
  • ユーザーを飽きさせず、離脱を防ぎたい方
  • ユーザーの処理待ちに伴うストレスや不安を軽減させたい方

【この記事を読むメリット】
手軽にアプリにアニメーションを導入することが出来ます。

【結論】
LottieやRiveなどのアニメーションフレームワークを使用すると、手軽にローディングアニメーションを取り入れることが出来ます。

目次

アニメーション実装方法の選択

Flutter でアニメーションを作成するときは、さまざまな方法があります。どのようなアニメーションを表示したいかで、選択するものが変わってきます。

Flutter公式ページでディシジョンツリー(Decision Tree)が用意されているので、それを元に選択すると良いと思います。公式ページは英語で記載されているので、翻訳したものを掲載します。

引用:https://docs.flutter.dev/development/ui/animations

以下のように分類することができます。

アニメーションフレームワーク(LottieやRive(旧Flare)など)
CustomPainter
Implicit animations(暗黙的) AnimatedDefaultTextStyle
TweenAnimationBuilder
AnimatedFoo
Explicit Animation(明示的) FooTransition
AnimatedBuilder
AnimationWidget

アニメーションフレームワーク(LottieやRiveなど)

アニメーションフレームワーク(LottieやRiveなど)は、作成したいものがコードで行うのが難しい場合やアニメーションにSVG・ベクターの使用が含まれる場合に使用します。

CustomPainter

CustomPaintウィジェットを使用して、キャンバス上に様々な図形(線、円、四角形など)を描画をすることができます。

Implicit Animations(暗黙的なアニメーション)とExplicit Animation(明示的なアニメーション)

Implicit Animations(暗黙的なアニメーション)とExplicit Animation(明示的なアニメーション)は、ウィジェットのサイズ、スケール、位置などを変更することができます。例えば、ショッピングリストの商品の写真をカートのアイコンに移動させることができます。

Implicit Animations(暗黙的なアニメーション)には、簡単に使用出来るモーションアニメーションが用意されています。これらのタイプのアニメーションは、Implicit Animations(暗黙的なアニメーション)と呼ばれます。

アニメーションをより細かく制御したい場合は、明示的なアニメーションを使用する必要があります。曲線、期間(開始と終了)、およびトリガーの種類を指定して明示的に定義する必要があるアニメーションは、Explicit Animation(明示的なアニメーション)と呼ばれます。

ローディング向きアニメーションは?

CustomPainterやImplicit Animations(暗黙的なアニメーション)、Explicit Animation(明示的なアニメーション)は、ローディングアニメーションをするにはコード量が多くなり、簡単には作れません。LottieやRiveなどのアプリケーションフレームワークを使うことをお勧めします。

Lottie(ロッティ)とは

Lottieは、AdobeのAfter Effectsで作成したアニメーションをJSON形式(LottieFiles)にエクスポートするフレームワークです。LottieFilesはSVG と同様にベクター形式であるため、アニメーション化されたアイコンがどんなに小さくても大きくても、品質が低下することはありません。GIFより小さく、ほぼすべてのプラットフォーム(Mac、iOS、Android、Windowsの一部)に対応しています。問題は、AdobeのAfter Effectsをある程度使いこなせる人が必要になります。また、After Effectsの全機能は使えず、使用できるアニメーションには限りがあります。シンプルなアニメーションにする場合は、 Lottieを使用するのが最適です。

Rive(ライブ)とは

一方、アニメーションに重点を置き、より詳細な制御が必要な場合はRive(旧Flare)がお勧めです。Lottie よりも高速で、サイズが小さく、消費するメモリも少なくて済みます。またAfter Effects などの他社ツールを使用せず独自のRiveエディタを使うことができます。ただし、After Effectsの方が機能が多く、使いやすいです。

Lottie・Riveの実装方法

インターネット上にあるLottieファイル(拡張子json)、Riveファイル(拡張子riv)を使用して、どのように動かすのかを確認します。

Step0. main.dart等にLottie,Riveそれぞれの呼び出しボタンを作成

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("アニメーション"),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            ElevatedButton(
              child: const Text('Lottie Loading'),
              onPressed: () {
                _showLottieLoading();
              },
            ElevatedButton(
              child: const Text('Rive Loading'),
              onPressed: () {
                _showRiveLoading();
              },
            ),
          ],
        ),
      ),
    );
  }

Lottie実装方法

Step1. pubspec.yaml に次の行を追加します。 (そして flutter pub get を実行します)

dependencies:
  lottie: ^2.1.0

Step2. main.dart等にimport文を追加

import 'package:lottie/lottie.dart';

Step3. main.dart等にコード記載
呼び出しボタン押下時のアニメーション表示部分を作成します。

  _showLottieLoading() {
    showGeneralDialog(
        context: context,
        barrierDismissible: false,
        transitionDuration: Duration(milliseconds: 250), 
        barrierColor: Colors.black.withOpacity(0.5), 
        pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) {
          return Container(
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height,
            color: Colors.white,
            child: Column(
              mainAxisAlignment:MainAxisAlignment.center,
              crossAxisAlignment:CrossAxisAlignment.center,
              children: [
                Lottie.network(
                    'https://assets10.lottiefiles.com/packages/lf20_07PkRX.json'),
                ElevatedButton(
                  child: const Text('LoadingOff'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                )
              ],
            ),
          );
        }
    );

Rive実装方法

Step1. pubspec.yaml に次の行を追加します。 (そして flutter pub get を実行します)

dependencies:
  rive: ^0.10.0

Step2. pubspec.yaml にAssetsを追加しRivファイルを格納

assets:
  - assets/

サンプル用のRivファイルはRiveホームページのコミュニティよりダウンロードしたものを上記assetsフォルダに格納します。

Step3. main.dart等にimport文を追加

import 'package:rive/rive.dart';

Step4. main.dart等にコード記載
呼び出しボタン押下時のアニメーション表示部分を作成します。

"Sway Loading animation" by niek1 is licensed under CC BY 4.0

  _showRiveLoading() {
    showGeneralDialog(
        context: context,
        barrierDismissible: false,
        transitionDuration: Duration(milliseconds: 250),
        barrierColor: Colors.black.withOpacity(0.5), 
        pageBuilder: (BuildContext context, Animation animation, Animation secondaryAnimation) {
          return Container(
            width: MediaQuery.of(context).size.width,
            height: MediaQuery.of(context).size.height,
            color: Colors.white,
            child: Column(
              mainAxisAlignment:MainAxisAlignment.center,
              crossAxisAlignment:CrossAxisAlignment.center,
              children: [
                SizedBox(
                  height: 300,
                  child: RiveAnimation.asset('assets/loading.riv'),
                ),
                ElevatedButton(
                  child: const Text('LoadingOff'),
                  onPressed: () {
                    Navigator.pop(context);
                  },
                )
              ],
            ),
          );
        }
    );
  }

Lottie・Riveを使用する上での制限事項

Lottie、Riveは無料で始めることが出来ますが、無料枠には制限があります。価格については各公式ホームページをご確認ください。また、インターネット上にあるLottieファイル、Riveファイルを使用する場合はライセンスをご確認の上、使用してください。

Lottie、Riveを使用することが難しい場合、サイズや解像度に問題なければ上記のLottieファイル、Riveファイルの呼び出し部分を以下のようにGIF表示にしてもローディングアニメーションとして使用出来ます。

Image.asset("assets/loading.gif"),

まとめ

LottieやRiveを使用すると複雑なアニメーションを少ないコード量で表示することが出来ます。しかもLottieファイル、RiveファイルともにGIFよりサイズも小さく(両方とも10KB以下)、綺麗に表示することが出来ました。ローティング中にちょっとしたアニメーションを取り入れたい方は是非使ってみてください。

採用情報はこちら
目次