4
1

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] 三(卍^o^)卍←こいつで学ぶアニメーション

Last updated at Posted at 2019-09-15

これは何?

[CSSアニメーション]三(卍^o^)卍←こいつのこれ→卍を回したい

  • mame_hashbill氏の記事を読み,「ぼくもこれやりたい!」ってなったため
  • Flutterのアニメーション復習したかったため
  • DartPadでFlutterが動かせるようになっていたのでリンクで共有するやつをやりたかったため

以上の理由でやりました.
怒られたら消します.

まずはこれを見てくれ

スマホでも動くけど,横画面にするかPCで見たほうが良いです.
右上のRunボタンを押すと,アイツが動き出すはずです.
スクリーンショット 2019-09-10 13.49.45.png

実装

Flutterのアニメーションにはいくつか実装の方法があるんですが,今回は細かくアニメーションを制御できる最も基本的な書き方のうち2種類を使います.
2つとも同じような方法ですが,実際に書いてみて比べたくなったのでやってみました.

普通にAnimationを直に使う場合

公式チュートリアル
これの通り.ドゥルルル自体の移動に使ってます.

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

    //省略
    
    _bodyController = AnimationController(
      duration: const Duration(milliseconds: 2500),
      vsync: this,
    );
    _bodyAnimation = Tween<double>(begin: 0, end: 600).animate(_bodyController)
      ..addListener(() => setState((){}));
    _bodyController.repeat();
    
  }
  
  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(_bodyAnimation.value, 0),
      child: _buildCrazy(context),
    );
  }

AnimatedBuilder を使う場合

公式ドキュメント
これの通りです.腕の回転ですね.

@override
  void initState() {
    super.initState();
    _armController = AnimationController(
      duration: const Duration(milliseconds: 500),
      vsync: this,
    )..repeat();
    
    //省略
  }

Widget _buildCrazy(BuildContext context) {
    return AnimatedBuilder(
      animation: _armController,
      builder: (context, child) {
        return Row(
          children: <Widget>[
            const Text('三('),
            Transform.rotate(
              angle: _armController.value * 2.0 * math.pi,
              origin: Offset.zero,
              child: Text('卍'),
            ),
            const Text('^o^)'),
            Transform.rotate(
              angle: _armController.value * 2.0 * math.pi,
              origin: Offset.zero,
              child: Text('卍'),
            ),
            const Text('ドゥルルルルルルルル'),
          ],
        );
      },
    );
  }

(アニメーションタイプが回転でrepeatメソッド使うのもまんまだったのでびっくり)

2つの実装,どっち使えばいいの?

ここでは簡単な実装だったので,どっちでもいいじゃんって感じになってるんですけど,一応使い分けポイントとしては

  • AnimatedBuilder の場合, animation にコントローラーを直接突っ込める
    • つまり Animation の宣言をしなくてもアニメーションできて手間が減る

(箇条書きしたけど一つしか出なかった)
というのがパッと見わかります.

しかし上記の使い分けには罠があります.
確かに AnimatedBuilder にコントローラーを突っ込めば楽ができますが,この場合アニメーションの種類は0.0 ~ 1.0のTweenアニメーションで固定になります.またイージングカーブもLinear固定になります.

でも, AnimatedBuilder のプロパティ名って animation ですよね?

そう,普通に Animation が突っ込めます.

  AnimationController _armController;
  Animation<double> _armAnimation;

  @override
  void initState() {
    super.initState();
    _armController = AnimationController(
      duration: const Duration(milliseconds: 500),
      vsync: this,
    )..repeat();
    
    _armAnimation = Tween<double>(begin: 0, end: 2.0 * math.pi).animate(_armController);
  }

  @override
  Widget build(BuildContext context) {
    return _buildCrazy(context);
  }

  Widget _buildCrazy(BuildContext context) {
    return AnimatedBuilder(
      animation: _armAnimation,
      builder: (context, child) {
        return Row(
          children: <Widget>[
            const Text('三('),
            Transform.rotate(
              angle: _armAnimation.value,
              origin: Offset.zero,
              child: Text('卍'),
            ),
            const Text('^o^)'),
            Transform.rotate(
              angle: _armAnimation.value,
              origin: Offset.zero,
              child: Text('卍'),
            ),
            const Text('ドゥルルルルルルルル'),
          ],
        );
      },
    );
  }

腕のアニメーションだけ抜き出して,書き換えてみました.
これで細かいアニメーションの設定もできるし,更にリスナーを登録する必要がないので無駄にsetState書かなくてスッキリですね😋

結局の所

Animatedなんちゃら系の一番ラクなWidgetを使わずにアニメーションを実装する場合,基本的にAnimatedBuilderで組むのがよさそうです.
公式チュートリアルMonitoring the progress of the animation でやっているような場合分けも addStatusListener するだけで済みます.

結果的に書く量ってそこまで変わらない気がするので,どちらの方法でやってもあまり変わらない……? もし明確な違いがあったらコメントで教えて下さい.

4
1
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
4
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?