【Flutter】Provider()使い方、サンプルコード

こんにちは!本記事では、Provider()というウィジェットについて、サンプルコードを用いながら実践的に説明しています。

目次

Provider()とは

Provider()はパッケージの一つです。

Provider()を使うと、リアルタイムで変数を変化させたり、状態管理をすることができます。TextFieldに入れたものを他の画面でリアルタイムで見せたい・・という時などに便利なウィジェットです。

基礎になる構文

Provider()を使うにあたって必要になる構文は、三つあります。

  • ChangeNotifierProvider<変数を格納しているクラス名>(create: , child: )
    ChangeNotifierのクラス内でnotifyListeners()が宣言された時、変数を変更できるようにするウィジェット
  • ChangeNotifier→extendsとしてclassに使うと、notifyListeners()が使えるようになる
  • notifyListeners()→これを使うと、ChangeNotifierProvider内にあるウィジェットの変数を更新させる
  • Provider.of<変数を格納しているクラス名>(context)→変数を呼び出す際に使用する

使い方としては下記のような感じです。変数を変化させるときにnotifyListeners()を含めることで、リアルタイムで他のクラスにある変数を変化させることができます。

ChangeNotifierProvider<K>(
 create: (context) => K() ,
 child: Page(),
)

class Page extends StatelessWidget{
@override
Widget build(BuildContext context){
return Text(Provider.of<K>(context).k);   //text
}
}

class K extends ChangeNotifier {
String k = 'text';
void changeK(String newText){
k = newText;
notifyListeners();
}
}

説明だけだと難しいので、実際に実装してみましょう。

使い方チュートリアル

実際にProvider()を使ってアプリを実装してみましょう。

今回作成するのは左の動画のように、上からAppBar()TextField()Text()を設置したデザインです。

TextField()で入力された文字はK()というクラスに格納され、入力文字が変化したと同時にAppBar()Text()にも反映されます。

ページのデザイン構成は以下の通りです。MyApp()の下にPage1()があり、Page1()の中にColumn()としてPage2, Page3が格納されています。

Provider()をインポートする

公式ページを参考に、パッケージをインポートしましょう。(flutter pub add providerです。)

パッケージのインポート方法がわからない場合は以下の記事を参考にしてください。

あわせて読みたい
【Flutter】パッケージをインストール/アンインストールする方法について~コマンドと一緒に紹介 パッケージとは、Widgetをまとめたものです。目的に沿ったパッケージを導入することで完成されたWidgetを使って簡単に開発ができるため、手間が大幅に短縮されます。 本...

変数を格納するクラスKの作成

変数kを格納するクラスKを作成しましょう。ChangeNotifierと設定するのを忘れずに。

class K extends ChangeNotifier {
  String k = 'text';
}

MyApp()での設定

下に、MyApp()付近のコードを示します。MaterialAppの中でChangeNotifierProvider<K>を作成します。ChangeNotifierProvider<K>create:child:が必要なので、以下のように宣言しましょう。これで、childで宣言されているウィジェット内はリアルタイムで変数が変わるように、常に準備している状態になります。

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: ChangeNotifierProvider<K>(
          create: (context) => K(),
          child:  Page1() ,
          ),
      );
  }
}

Page1()の作成

Page1は以下のように作成します。わかりやすいようにピンクの背景色をつけました。

AppBarのtitleにクラスK内にある変数のkを使用しています。さらにそのbodyでは、TextField()を格納しているPage2()、Text()を格納しているPage3()を配置します。

class Page1 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return  Scaffold(
      backgroundColor: Colors.pink.shade100,
      appBar: AppBar(
        title: Text(Provider.of<K>(context).k)
      ),
      body: Column(
          children: [Page2(), Page3()]),
    );
  }

}

Page2()の作成

Page2では、TextFieldを配置します。TextField内の変数が変化したとき(onChanged)、kをその変数にした後、notifyListeners()を呼び出します。これを忘れるとKクラス内にあるk自体の値は変化しますが、AppBar()内やText()内にある変数に関しては、リアルタイムで変化しません。notifyListeners()が各変数に変数が変わったからそっちも変えてね〜って呼びかけているようなイメージです。

class Page2 extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return TextField(
      cursorColor: Colors.white,
      onChanged: (newText){
        Provider.of<K>(context, listen: false).k = newText;
        Provider.of<K>(context, listen: false).notifyListeners();
      },
    );
  }
}

Page3()の作成

Page3()でもText()を配置しましょう。

class Page3 extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Text(
        Provider.of<K>(context, listen: false).k,
    style: TextStyle(
      backgroundColor: Colors.yellow.shade200
    ),);

  }
}

TextFieldに文字を打って、変数が変わることを確認しよう

ここまで実装できたら、実際に実行してTextField内で文字を打ってみましょう。AppBar()の文字とText()の文字がリアルタイムで変化すると思います。

*全てのコードは、この記事の最後に載せておきます。

エラーが出た場合の対処方法

“Could not find the correct Provider<> above this Widget.”というエラーが出た場合は、ChangeNotifierProvider<K>をさらに上位のクラスに置くようにしてください。

あわせて読みたい
【Flutterエラー解決】”Could not find the correct Provider<> above this Widget.”の解決法 こんにちは!本記事では、Provider()を使用したときに出てくるエラーについて解決方法をご紹介します。 エラー文は以下の通り。 The following ProviderNotFoundExcepti...

関連記事

Flutter全般の記事まとめ

あわせて読みたい
【Flutter】記事まとめ こんにちは!本記事ではFlutterに関する記事を体形立ててまとめています。目次としてお使いください。 【全体図】 全ての記事を図でまとめています。(2022年2月22日現在...

今回作成したコード全文

import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
        home: ChangeNotifierProvider<K>(
          create: (context) => K(),
          child:  Page1() ,
          ),
      );
  }
}
class Page1 extends StatelessWidget{
  @override
  Widget build(BuildContext context) {
    // TODO: implement build
    return  Scaffold(
      backgroundColor: Colors.pink.shade100,
      appBar: AppBar(
        title: Text(Provider.of<K>(context).k)
      ),
      body: Column(
          children: [Page2(), Page3()]),
    );
  }

}
class Page2 extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return TextField(
      cursorColor: Colors.white,
      onChanged: (newText){
        Provider.of<K>(context, listen: false).k = newText;
        Provider.of<K>(context, listen: false).notifyListeners();
        //print(Provider.of<K>(context, listen: false).k);
      },
    );
  }
}
class Page3 extends StatelessWidget{
  @override
  Widget build(BuildContext context){
    return Text(
        Provider.of<K>(context, listen: false).k,
    style: TextStyle(
      backgroundColor: Colors.yellow.shade200
    ),);

  }
}

class K extends ChangeNotifier {
  String k = 'text';
}

参考記事

Not found the post.
よかったらシェアしてね!

コメント

コメントする

CAPTCHA


目次
閉じる