5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Flutter自作アニメーションの作り方

Last updated at Posted at 2020-03-24

Flutter自作アニメーションの作り方

この記事でやること

  • 0% から 100% に文字を変化させるアニメーションを作成する

HeroWidgetなど公式のWidgetを使うとFlutterでは簡単に単純なアニメーションを作成することができるが、
自分で細かく調整したい場合はAnimationControllerを使った方がやりやすかったので紹介。

面倒くさいのでHeroWidgetのようなアニメーションを付けてくれるWidgetをまず先に探して、
どうしても無かった場合はこの方法でどうにかする、というスタンスでいいと思う。

事前知識

  • Flutter Stateful Widget の使い方
    • setStateでWidgetを作り直すなど

全体の流れ

  • テスト画面作成
  • Ticker作成
  • Controller作成
  • 文字列に代入

テスト画面を作る

文字を中央に表示するだけ。

今回はmain.dartを書き換えているが、適宜アニメーションを付けたいWidgetに置き換える。
statefull widgetで作る必要があることに注意。

以下サンプルコード

import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      debugShowCheckedModeBanner: false,
      home: Scaffold(
        appBar: AppBar(
          title: Text('custom animation test'),
        ),
        body: Center(
          child: Text(
            //TODO animate text from 0 to 100%
            '0%',
            style: TextStyle(
              fontSize: 40.0,
            ),
          ),
        ),
      ),
    );
  }
}

Screen Shot 2020-03-25 at 1.01.53 AM.png

アニメーション作成

Ticker作成

まずはTickerを作る。

Tickerは0から1の値を変動していく。
Tickerの値が変化するたびに新しいフレームを作成していき、繋げてみると動いているように見えるということ。

これは単純にアニメーションを付けたいWidgetにMixinをつけることで作成できる。

例えば作るアニメーションが1つの場合は

with SingleTickerProviderStateMixin

をアニメーションをしたいWidgetに付ける。

サンプル


class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  @override
  Widget build(BuildContext context) {
    ....

Controller作成

アニメーションの開始するタイミングや、変動する範囲を決められる。

今回は0から100までの値を3秒間かけて変化するコントローラーを作る。
コントローラーはWidget作成時に最初に完成している必要があるのでinitState()内で作成する。

(flutterのwidgetが実行される順番は initState >>> build >>> dispose)

サンプル

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  AnimationController controller;

  @override
  void initState() {
    super.initState();

    controller = AnimationController(
      vsync: this, // このWidgetのTickerと同期するように指定
      duration: Duration(seconds: 3),
      lowerBound: 0.0, 
      upperBound: 100.0, 
    );
  }

  @override
  Widget build(BuildContext context) {
    ...

アニメーションが終わったらコントローラーを削除する。
これを行わないとWidgetが削除されてもコントローラーの計算が永遠と行われることになる。

Widget削除時に実行されるdispose内に記述する。


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

Controllerを動かす

値が0から100まで3秒間かけて変化するControllerを

initState内で開始させるコマンドcontroller.forward();を書き、

Widget作成時に実行されているか確認してみる。

サンプル


  @override
  void initState() {
    super.initState();

    controller = AnimationController(
      vsync: this, // このWidgetのTickerと同期するように指定
      duration: Duration(seconds: 3),
      lowerBound: 0.0,
      upperBound: 100.0,
    );

    controller.forward(); // アニメーション開始

    controller.addListener(() {
      print(controller.value); // コンソールで値を確認
    });
  }

実行結果

Hot Restartすると


Restarted application in 956ms.
flutter: 0.0
flutter: 0.0
flutter: 12.396533333333332
flutter: 12.9521
flutter: 14.0632
flutter: 14.618733333333333
flutter: 15.174299999999999
flutter: 15.174299999999999
flutter: 15.174299999999999

...

flutter: 94.598
flutter: 95.15356666666666
flutter: 95.70913333333334
flutter: 96.26466666666667
flutter: 96.82023333333333
flutter: 97.3758
flutter: 97.93133333333334
flutter: 98.4869
flutter: 99.0425
flutter: 99.598
flutter: 100.0

のように値が0から100まで変化していることが確認できる。

Contoroller.value をテキストに代入

Contoroller.valueが変化するたびにWidgetを作り直したい。

そのためにcontroller.addListener内にsetStateを書く。


    controller.addListener(() {
      print(controller.value);
      setState(() {});
    });

main.dart内で0%を表示していたテキストをcontroller.value.toInt()に置き換える。

          child: Text(
            //TODO animate text from 0 tp 100%
            '${controller.value.toInt()}%',
            style: TextStyle(
              fontSize: 40.0,
            ),
          ),

Hot Restartすると

めんどう

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?