18
6

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 1 year has passed since last update.

Flutterでmixinを使う

Last updated at Posted at 2023-04-27

はじめに

Flutterのアーキテクチャについての議論は様々で、infrastructure, dataSource, domainの単位でフォルダを大きく切り分けるlayered_architectureだったり、機能単位でフォルダを大きく分けるfeature_architectureなどが存在しています。

(以下の推奨を見ると、feature型の方が推奨されている感じですね)

その際に、あるあるなのは「共通実装どうしよう」という悩みです。

今回は、その共通化のための1手段であるMixinの使い方について記載します

Mixinとは?

Mixinは、新しい継承階層を作ることなく、クラスに機能を追加する方法です。つまり、元のクラスを変更することなく、特定のメソッドやプロパティをクラスに追加することができます。

基本的な定義の仕方

mixinで定義するだけです。他のクラスを拡張してはならず、そのメソッドとプロパティはabstractとして宣言しなければなりません。

mixin SampleMixin {
  void printMessage(String message) {
    print(message);
  }
}

使い方

使い方は以下のようにwithを使います。

class Person with SampleMixin {
  String name;

  Person(this.name);

  void introduce() {
    printMessage("Hello, my name is $name.");
  }
}

使い方の例

例えば、ログイン・ログアウトはAppBar, 設定画面, プロフィール画面などで使い回すこともあるのではないでしょうか

mixin AuthMixin {
  void login() {
    // ログイン
  }

  void logout() {
    // ログアウト
  }
}

また、定型的なバリデーションもあれば使い回しも可能です。

mixin ValidationMixin {
  bool emptyCheck(String text) {
    return text.isNotEmpty;
  }

  bool validateEmail(String email) {
    RegExp regex = RegExp(r'^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$');
    return regex.hasMatch(email);
  }
}

以上のようにすることでutilityなどの使用を避けたコードの再利用が可能となります。
また、Flutterではデフォルトでウィジェットに対するmixinがいくつか存在しています。

SingleTickerProviderStateMixin:

このmixinは、アニメーションを扱う際に役立ちます。SingleTickerProviderStateMixinは、アニメーションコントローラーにTicker(フレームごとの時間差を提供するオブジェクト)を提供するために使用されます。このmixinを使用することで、状態クラス内でアニメーションコントローラーを簡単に初期化・管理できます。

class _MyAnimatedWidgetState extends State<MyAnimatedWidget> with SingleTickerProviderStateMixin {
  AnimationController _controller;

  @override
  void initState() {
    super.initState();
    _controller = AnimationController(
      vsync: this, // 使用するTickerProviderを指定
      duration: const Duration(seconds: 2),
    );
  }

  // 必要な箇所でアニメーションを実装
}

AutomaticKeepAliveClientMixin:

このmixinは、ウィジェットの状態を保持するのに役立ちます。一部のウィジェットは、親ウィジェットが再構築される際に状態を保持したい場合があります。これを実現するために、AutomaticKeepAliveClientMixinを使用できます。このmixinを使用すると、ウィジェットが破棄されるのを防ぎ、状態を保持できるようになります。

class _MyStatefulWidgetState extends State<MyStatefulWidget> with AutomaticKeepAliveClientMixin {
  // 状態を保持したいデータやウィジェットの実装

  @override
  bool get wantKeepAlive => true; // 状態の保持を有効化

  @override
  Widget build(BuildContext context) {
    super.build(context); // 必ずsuper.build(context)を呼び出すこと
    // ウィジェットの構築
  }
}

WidgetsBindingObserver:

このmixinは、アプリのライフサイクルイベントを監視するために使用されます。WidgetsBindingObserverを使用すると、アプリがアクティブ化・非アクティブ化されたときや、画面の向きが変わったときなどのイベントに対応できます

以下の例では、WidgetsBindingObserverを使用して、アプリのライフサイクルイベントを監視しています。それぞれのイベントが発生したときの処理をdidChangeAppLifecycleStateメソッド内に実装することができます。これにより、アプリの状態に応じて適切な処理を実行することが可能になります。

class _MyAppState extends State<MyApp> with WidgetsBindingObserver {
  @override
  void initState() {
    super.initState();
    WidgetsBinding.instance.addObserver(this); // オブザーバーの登録
  }

  @override
  void dispose() {
    WidgetsBinding.instance.removeObserver(this); // オブザーバーの解除
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    super.didChangeAppLifecycleState(state);
    switch (state) {
        case AppLifecycleState.resumed:
            // アプリがアクティブ化されたときの処理
            break;
        case AppLifecycleState.inactive:
            // アプリが非アクティブ化されたときの処理
            break;
        case AppLifecycleState.paused:
            // アプリが一時停止されたときの処理
            break;
        case AppLifecycleState.detached:
            // アプリがウィジェットツリーから削除されたときの処理
            break;
    }
  }

  @override
  Widget build(BuildContext context) {
    // ウィジェットの構築
  }
}

以上となります。utilityを作ってしまうと簡単かもしれませんが、そうするとutilityが肥大化してしまう場合がありますね。そのため、今回のmixinはそれを避ける1手として参考になればと思います。

18
6
1

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
18
6

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?