study-note

Provider

目次

ChangeNotifier

基本構文

class AuctionViewModel extends ChangeNotifier {
  // 状態(プロパティ)
  int _count = 0;
  int get count => _count;

  // 状態を変更するメソッド
  void increment() {
    _count++;
    notifyListeners(); // ここでリスナーに通知
  }
}

メソッド

Provider系クラス

Provider<T>

Provider<T>(
  create: (context) => Tのインスタンス,
  child: Widget,
)

ChangeNotifierProvider<T extends ChangeNotifier>

ChangeNotifierProvider<T>(
  create: (context) => Tのインスタンス,
  child: Widget,
)

MultiProvider

MultiProvider(
  providers: [
    ChangeNotifierProvider(create: (_) => ViewModelA()),
    Provider(create: (_) => ServiceB()),
  ],
  child: Widget,
)

データの取得

Provider.of<T>(context, {listen = true})

Provider.of<T>(context, listen: true/false)

context.read<T>()

context.watch<T>

context.select<T, R>(R selector(T value))

context.select<T, R>(
	(value) => value.someField
)

Widgetでの監視(画面更新)

Selector<T, R>

Selector<T, R>(
  selector: (context, value) => value.someField,
  builder: (context, field, child) {
    return Widget;
  },
)

Consumer<T>

Consumer<T>(
  builder: (context, value, child) {
    return Widget;
  },
)

サンプルコード

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

void main() {
  runApp(
    ChangeNotifierProvider(
      create: (_) => MyModel(),
      child: MyApp(),
    ),
  );
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        body: Center(
          child: Consumer<MyModel>(
            builder: (context, model, child) {
              return Text('Count: ${model.count}');
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => context.read<MyModel>().increment(),
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

流れまとめ

  1. Model(状態を持つクラス)作成 ```dart import ‘package:flutter/material.dart’;

class Counter extends ChangeNotifier { int _count = 0;

int get count => _count;

void increment() {
  _count++;
  notifyListeners(); // UIに変更を通知
}   }   ``` 2. `Provider`で包む   ```dart   import 'package:provider/provider.dart';

void main() { runApp( ChangeNotifierProvider( create: (_) => Counter(), child: const MyApp(), ), ); }

3. UIで使う
  ```dart
  class CounterPage extends StatelessWidget {
    const CounterPage({super.key});

    @override
    Widget build(BuildContext context) {
      final counter = context.watch<Counter>(); // データの購読

      return Scaffold(
        body: Center(
          child: Text('Count: ${counter.count}'),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => counter.increment(),
          child: const Icon(Icons.add),
        ),
      );
    }
  }