LoginSignup
7
1

More than 1 year has passed since last update.

MultiProvider classとは?

Last updated at Posted at 2022-03-26

Providerを勉強し直してみた...

今まで、ChageNotifire、Consumerし使ったことがなかった。
Provider.of(context);だとか、context.watch<>();って何だろうと考えていた???

こちらの公式ドキュメントで解説されていた。
https://pub.dev/documentation/provider/latest/provider/ChangeNotifierProvider-class.html

最近になって何となくわかってきた...

とりえずサンプルを作ってプログラムの挙動を調べてみた...

フォルダ構成はこんな感じ
スクリーンショット 2022-03-26 21.02.05.png

person_model.dart

import 'package:flutter/foundation.dart';

class Person with ChangeNotifier {
  final String firstName = "Jboy";
  final String lastName = "Hashimoto";
  int age = 0;

  void say() {
    // コンソールに表示
    print("Hello Person!!!");
    notifyListeners();
  }

  void addAge() {
    age++;
    notifyListeners();
  }
}

pet_model.dart

import 'package:flutter/foundation.dart';

class Pet with ChangeNotifier {
  final String petName = 'ポチ';
  int bowbow = 0;

  void bowCount() {
    // 吠えた数
    bowbow++;
    notifyListeners();
  }
}

home_page.dart

import 'package:flutter/material.dart';
import 'package:person_mvvm/model/person_model.dart';
import 'package:person_mvvm/model/pet_model.dart';
import 'package:provider/provider.dart';

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

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          mainAxisSize: MainAxisSize.max,
          children: [
            Text(
              '私の名前は、${context.watch<Person>().firstName}',
              style: const TextStyle(fontSize: 20.0),
            ),
            const SizedBox(height: 10.0),
            Text(
              '私の苗字は、${context.select<Person, String>((Person person) => person.lastName)}',
              style: const TextStyle(fontSize: 20.0),
            ),
            Text(
              '年齢は、${context.select<Person, int>((Person person) => person.age)}',
              style: const TextStyle(fontSize: 20.0),
            ),
            const SizedBox(height: 10.0),
            ElevatedButton(
                onPressed: () => context.read<Person>().addAge(),
                child: const Text(
                  '歳をとっていく...',
                  style: TextStyle(fontSize: 20.0),
                )),
            const SizedBox(height: 10.0),
            ElevatedButton(
                onPressed: () => context.read<Person>().say(),
                child: const Icon(Icons.add_call)),
            const SizedBox(height: 10.0),
            Text(
              'Jboyの愛犬の名前は、${context.watch<Pet>().petName}',
              style: const TextStyle(fontSize: 20.0),
            ),
            const SizedBox(height: 10.0),
            Text('吠えた回数は、${context.select<Pet, int>((Pet pet) => pet.bowbow)}'),
            ElevatedButton(
                onPressed: () => context.read<Pet>().bowCount(),
                child: const Icon(Icons.add_alert)),
          ],
        ),
      ),
    );
  }
}

main.dart

import 'package:flutter/material.dart';
import 'package:person_mvvm/model/person_model.dart';
import 'package:person_mvvm/model/pet_model.dart';
import 'package:provider/provider.dart';

import 'views/home_page.dart';

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Person()),
        ChangeNotifierProvider(create: (_) => Pet()),
      ],
      child: const MyApp(),
      ),
    );
}

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

  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Person mvvm',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const HomePage(),
    );
  }
}

スクリーンショット 2022-03-26 21.04.42.png

スクリーンショット 2022-03-26 21.05.19.png

今回、何でこんなコードを書いたのかというと、pub.devのProviderのExampleのサンプルコードを見て、Flutter大学のProviderと書き方が違って、ちんぷんかんぷんだったから!!!

これが、どんな意味なのか最近までわからなかった???

void main() {
  runApp(
    /// Providers are above [MyApp] instead of inside it, so that tests
    /// can use [MyApp] while mocking the providers
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Counter()),
      ],
      child: const MyApp(),
    ),
  );
}

公式のドキュメント

解説を日本語に訳すと、「複数のプロバイダを1つのリニアなウィジェットツリーに統合するプロバイダです。可読性を高め、プロバイダを何重にもネストしなければならないという定型的なコードを減らすために使用されます。」

どういうことかというと、複数のモデルのクラスをMultiProviderの中に書いて、呼び出すことができる。
だと思う...

私が書いたサンプルコードは、こんな感じで、PersonモデルとPetモデルを呼び出している。
この書き方を知ったのは、ミンプロっていう以前Udemyで購入したProviderの講座でした。
やっと、pub.devのサンプルコードの意味が理解できた...

void main() {
  runApp(
    MultiProvider(
      providers: [
        ChangeNotifierProvider(create: (_) => Person()),
        ChangeNotifierProvider(create: (_) => Pet()),
      ],
      child: const MyApp(),
      ),
    );
}

最後に

コピペばかりせずに、公式ドキュメントを見るようにするのが、良いのだがどうしてもわからないときは、メンターを雇った方がいいかもしれないですね。

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