🙌

【Flutter】providerパッケージを使用したカウンターの実装例

2023/01/26に公開

概要

この記事では、Flutterのproviderパッケージを使用した、カウンターの実装例を説明しています。

https://pub.dev/packages/provider

カウンターとは、Flutterプロジェクト作成時に作られる、初期アプリのことを指します。

今回のサンプル実装では、次のウィジェット、クラスを使用しています。
ProviderCounterAppは、カウントをインクリメントするボタンを持つウィジェットです。
ProviderCounterScreenProviderCounterAppウィジェットの親ウィジェットです。
Counterは、現在のカウントを表示するウィジェットで、ProviderCounterAppを親に持ちます。
CounterModelChangeNotifierを継承したクラスであり、カウントの保持や、カウントを増加させる処理をふるまいとして持ちます。

providerパッケージをインストールする

pubspec.yamlにproviderパッケージを追加し、pub getを実行します。

dependencies:
  flutter:
    sdk: flutter

  provider: ^6.0.5

ChangeNotifierを継承したクラスを作成する

カウントの保持、そしてカウントを増加させるふるまいを持った、CounterModelを作成します。
コードはつぎに示します。

class CounterModel extends ChangeNotifier {
  int value = 0;

  void increment() {
    value += 1;
    notifyListeners();
  }
}

このコードは、incrementメソッド内で、notifyListeners()を呼び出します。これにより、リスナーに値が変更されたことを通知します。

状態を変更させる処理を呼び出すウィジェットを作成する

ProviderCounterAppBuildContextから、状態を保持しているCounterModelのインスタンスを取得し、そのふるまいを呼び出します。

実装例をつぎに示します。

class ProviderCounterApp extends StatelessWidget {
  const ProviderCounterApp({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text("Provider Counter"),
      ),
      body: const Counter(),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          var counter = context.read<CounterModel>(); // (1)
          counter.increment(); // (2)
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}

(1)でcontext.read<T>()を使用してCounterModelのインスタンスを取得し、CounterModel.increment()を実行します(2)。

ChangeNotifierのインスタンスを提供する親ウィジェットを作成する

つぎは、ProviderCounterScreenを作成します。このウィジェットはChangeNotifierのインスタンスを子孫に提供する、ChangeNotifierProviderを返します。
ChangeNotifierのインスタンスを参照するウィジェットより、上位のウィジェットがChangeNotifierProviderを返すようにします。ProviderCounterApp内でChangeNotifierのインスタンスを参照しているため、このウィジェットでreturnすることになります。

class ProviderCounterScreen extends StatelessWidget {
  const ProviderCounterScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return ChangeNotifierProvider<CounterModel>(
      create: (BuildContext context) => CounterModel(),
      child: const ProviderCounterApp(),
    );
  }
}

状態を参照して表示するウィジェットを作成する

最後に、状態を参照して、その値を表示するCounterを作成します。
ChangeNotifierProviderを通して渡ってきたChangeNotifierのインスタンスを、Consumer<T>を用いて参照します。

class Counter extends StatelessWidget {
  const Counter({Key? key}) : super(key: key);

  
  Widget build(BuildContext context) {
    return Center(
      child: Consumer<CounterModel>(
        builder: (context, counter, child) => Text(
          '${counter.value}',
          style: const TextStyle(
            fontSize: 36.0,
          ),
        ),
      ),
    );
  }
}

まとめ

以上がproviderパッケージを使ったカウンターのサンプル実装です。
今回使用したコードと同様のコードをGitHubで公開していますので、よろしければ参考にしてください。

https://github.com/aiiro/flutter-implementation-samples/blob/main/provider_sample

参考

https://docs.flutter.dev/development/data-and-backend/state-mgmt/simple

Discussion