0
0

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 Provider/Consumer による状態管理

Posted at

Provider/Consumerを利用した学習コードの作成

  • ChangeNotifierを実装したCartModelを作成。
  • ChangeNotifierのメソッド一覧を見ると、addListenr,removeListener,notifyListenersが羅列されている。Javaで言うところのEvent Listenerのようなものとなんとなく理解。
  • 状態管理するモデルのデータを反映したいツリーの1つ上の階層で、Providerとして登録(設定)すると、配下のツリーにデータ更新時のイベントが通知される仕組みのようだ。
  • 状態更新を受け取る側(Widget)をConsumerで囲ってあげることで、対象のWidgetで通知を受け取ることができる。
  • Consumerは上位ツリーで受け取ることもできるが、Widgetのrebuildにも影響があるため、また更新が必要なWidgetに範囲を狭めた方が可読性もあり良いとのこと。

「shuffle」ボタンを押下する度に表示データが再描画されるコード

なんとなくの感覚で書いたので、より詳しく調べて学んでいく必要がある。listenをtrueにすると実行時エラーが発生する。ドキュメントをろくに読んでいないので、通知を受け取るとループするとかそんな感じなのか。

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

class CartModel with ChangeNotifier {
  List<int> values = [1, 2, 3, 4, 5];
  void shuffle() {
    values.shuffle();
    print(values);   //デバッグ用
    notifyListeners();//通知発火
  }
}

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});
  @override
  Widget build(BuildContext context) {
    //Providerの登録
    //Provider1つの登録なのでMutiProviderを使う必要はないが、書きやすかったのでこちらを利用。
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<CartModel>(
          create: (context) => CartModel(),
        ),
      ],
      child: const MaterialApp(
        home: Home(),
      ),
    );
  }
}

class Home extends StatelessWidget {
  const Home({super.key});
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            //CartModelの値が更新されたらRow内の再描画を行いたいので、ここでConsumerを設定
            Consumer<CartModel>(
              builder: (context, CartModel model, child) => Row(
                mainAxisAlignment: MainAxisAlignment.center,
                children: [
                  //CartModelに保存された数字を順番にTextオブジェクト化
                  ...List.generate(
                    model.values.length,
                    (int index) => Text(model.values[index].toString()),
                  ),
                ],
              ),
            ),
            ElevatedButton(
              child: const Text('shuffle'),
              onPressed: () => {
                //登録されたProviderのうちCartModel型のものを取り出し、shuffleメソッドを実行。
                Provider.of<CartModel>(context, listen: false).shuffle(),
              },
            )
          ],
        ),
      ),
    );
  }
}

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?