Flutter開発入門53 Flutterアニメーションの最適化:AnimatedBuilderを使ったリファクタリング

Flutter

はじめに

Flutterでアニメーションを実装する際、コードが複雑になることがあります。特に、同じウィジェットを何度も再描画する場合や、アニメーションを適用する範囲が広がると、コードの見通しが悪くなりがちです。そんなときに役立つのがAnimatedBuilderです。

AnimatedBuilderを使うことで、Flutterのアニメーションコードを簡潔かつ効率的にリファクタリングでき、パフォーマンスも向上します。このチュートリアルでは、AnimatedBuilderを使用したリファクタリング方法について解説し、Flutterアプリでアニメーションを最適化する方法を学びます。

AnimatedBuilderとは

AnimatedBuilderは、Flutterのアニメーションを効率的に構築するためのウィジェットです。アニメーションの進行に応じてUIを再ビルドする際に、UIの変更が必要な部分だけを効率的に更新します。これにより、不要な再ビルドを避け、パフォーマンスが向上します。

主な特徴

  • パフォーマンスの向上:UI全体ではなく、変更が必要な部分のみを再ビルドすることで、パフォーマンスを最適化します。
  • コードの再利用性向上:アニメーションロジックを1箇所にまとめ、UIとロジックを分離できます。
  • シンプルな構造:アニメーションの進行に応じてUIを簡単に構築できます。

AnimatedBuilderの使い方

AnimatedBuilderによるリファクタリングの例

まず、AnimatedBuilderを使用しない場合の基本的なアニメーションコードを見てみましょう。このコードは、スケールアニメーションを実装していますが、setState()を使って再ビルドしているため、パフォーマンスに影響が出る可能性があります。

AnimatedBuilderを使わない例
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AnimationExample(),
    );
  }
}

class AnimationExample extends StatefulWidget {
  @override
  _AnimationExampleState createState() => _AnimationExampleState();
}

class _AnimationExampleState extends State<AnimationExample> with TickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Without AnimatedBuilder')),
      body: Center(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (context, child) {
            return Transform.scale(
              scale: _controller.value + 1,
              child: Container(
                width: 100,
                height: 100,
                color: Colors.blue,
              ),
            );
          },
        ),
      ),
    );
  }
}

解説

  • AnimationController:アニメーションの制御を行い、2秒ごとにスケールが繰り返されます。
  • AnimatedBuilderbuilderに渡した内容が、アニメーションの進行に応じて自動で再ビルドされます。この例では、Transform.scaleを使ってウィジェットの大きさを変えています。

AnimatedBuilderによるリファクタリング

次に、AnimatedBuilderを使ってコードをリファクタリングし、アニメーションロジックを分離しつつ、不要な再ビルドを避ける最適化を行います。

AnimatedBuilderを使ったリファクタリング例
import 'package:flutter/material.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: AnimationExample(),
    );
  }
}

class AnimationExample extends StatefulWidget {
  @override
  _AnimationExampleState createState() => _AnimationExampleState();
}

class _AnimationExampleState extends State<AnimationExample> with TickerProviderStateMixin {
  late AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      duration: const Duration(seconds: 2),
      vsync: this,
    )..repeat(reverse: true);
  }

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Using AnimatedBuilder')),
      body: Center(
        child: AnimatedBuilder(
          animation: _controller,
          builder: (context, child) {
            return Transform.scale(
              scale: _controller.value + 1,
              child: child,
            );
          },
          child: Container(
            width: 100,
            height: 100,
            color: Colors.blue,
          ),
        ),
      ),
    );
  }
}

AnimatedBuilderによるリファクタリングの効果

このリファクタリングされたコードでは、Container(アニメーションの対象ウィジェット)がchildとしてAnimatedBuilderに渡されています。これにより、アニメーションの進行に関わらない部分は再ビルドされず、パフォーマンスが向上します。

重要なポイント
  • childAnimatedBuilderchildは、アニメーションの進行に影響を受けない部分です。これにより、再ビルドが最小限に抑えられ、パフォーマンスが向上します。
  • 効率的なリビルド:アニメーションによって変化するのはスケール(拡大・縮小)の部分だけで、UI全体を再ビルドしないため、不要なオーバーヘッドを避けることができます。

AnimatedBuilderのメリット

  1. コードの簡素化
    • AnimatedBuilderを使うことで、アニメーションロジックが分離され、UI部分とアニメーション部分をきれいに整理できます。結果的に、コードが読みやすく、保守しやすくなります。
  2. パフォーマンスの向上
    • UIの再ビルドを最小限に抑えることで、アニメーションのパフォーマンスが大幅に向上します。特に、複雑なアニメーションや大規模なウィジェットツリーで効果が発揮されます。
  3. 再利用可能なロジック
    • アニメーションのロジックを1箇所にまとめることで、同じアニメーションを他のウィジェットにも簡単に適用できます。コードの再利用性が向上し、開発効率もアップします。

まとめ

AnimatedBuilderは、Flutterでアニメーションを効率的に管理するための強力なツールです。不要な再ビルドを回避し、パフォーマンスを最適化するだけでなく、コードの読みやすさや保守性も向上させることができます。特に複雑なアニメーションや、頻繁にアニメーションが実行されるシナリオでは、その効果が顕著に現れます。

今回紹介した手法を活用して、アニメーションのパフォーマンスを向上させ、Flutterアプリをさらに魅力的なものにしてみてください!

コメント