【Flutter】カウンターアプリをStatelessWidgetで実装する【Riverpod編】

カウンターアプリとは

画面上の+ボタンを押すとカウントが1増加し、-ボタンを押すとカウントが1減少するシンプルなアプリです。

FlutterのサンプルアプリではStateful Widgetを使用していますが、今回はStatelessWidgetで実装します

Riverpodというパッケージでの解説となります。

使用環境

VScode バージョン: 1.84.2

Flutter バージョン: 3.76.0

flutter_riverpod: ^2.4.9

実装

動作画面と実装コードです。

counter_0

カウンターの初期値が0

counter_1counter_-1
+ボタンを押すとカウントが1増え、-ボタンを押すとカウントが1減る

以下実装コードです。

final nowCountProvider = StateProvider<int>((ref) => 0);

class CountApp extends ConsumerWidget {
  const CountApp({
    super.key,
  });

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final count = ref.watch(nowCountProvider);

    return Scaffold(
      appBar: AppBar(
        title: const Text('Riverpodでカウンター'),
      ),
      body: Center(
        child: Column(children: [
          const Text(
            '現在のカウント',
            style: TextStyle(fontSize: 24),),
          Text('$count',
            style: const TextStyle(fontSize: 32),),
          const SizedBox(height: 50,),
          Row(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                    minimumSize: const Size(100, 60),
                    shape: const CircleBorder()),
                onPressed: () =>
                    ref.watch(nowCountProvider.notifier).state = count - 1,
                child: const Text( '-',
                  style: TextStyle(fontSize: 24),
                ),
              ),
              ElevatedButton(
                style: ElevatedButton.styleFrom(
                    minimumSize: const Size(100, 60),
                    shape: const CircleBorder()),
                onPressed: () =>
                    ref.watch(nowCountProvider.notifier).state = count + 1,
                child: const Text( '+',
                  style: TextStyle(fontSize: 24),
                ),
              )
            ],
          )
        ]),
      ),
    );
  }
}

解説

final nowCountProvider = StateProvider<int>((ref) => 0);

final count = ref.watch(nowCountProvider);

現在のカウントをRiverpodのStateProviderで監視します。

監視している数字をnowCountProviderと定義します。

次にカウントをウィジェットの中でwatch(監視)したいのでnowCountProviderをcountと定義しておきます。

監視しているカウントを呼び出すイメージです。

こちらはConsumerWidgetの中に書きます。

ConsumerWidgetとは、state(状態)を監視することができる[StatelessWidget] のことです。

onPressed: () =>
                    ref.watch(nowCountProvider.notifier).state = count - 1,

onPressed: ボタンを押した時の動作をここに書きます。

ref.watch :状態を取得した上で、その変化を監視する。データが変化すると、そのデータに依存するウィジェットやプロバイダの更新が行われる。

notifirerでnowCountProviderの更新を依頼、nowCountProviderのstate(状態)を更新します。

「state = count – 1,つまり、今のカウントの状態から1を引いてください」という処理になる。

// ref.watchしているデータ(現在のカウント)
final count = ref.watch(nowCountProvider);

// watchしているデータのstateが変化したら画面も再描画される
Text('$count',
            style: const TextStyle(fontSize: 32),),

ref.watchするとデータの変更と共にウィジェットの再描画も行われるのでcount(現在のカウント)の表示も再描画される。

まとめ

いかがだったでしょうか?

ご意見、ご感想ありましたらお気軽にコメントしてください。

実際のアプリ開発の現場ではあまり StatefulWidget は使われないようです。

この機会にStatelessWidgetでの状態管理に挑戦してみてはいかがでしょうか。

【参考文献】

他にも状態管理に使えるライブラリはありますので宜しければこちらもご覧ください。

【GetXでカウンターアプリ】

コメント

タイトルとURLをコピーしました