ChangeNotifier
ViewModel
や状態保持クラスで継承するclass AuctionViewModel extends ChangeNotifier {
// 状態(プロパティ)
int _count = 0;
int get count => _count;
// 状態を変更するメソッド
void increment() {
_count++;
notifyListeners(); // ここでリスナーに通知
}
}
notifyListeners()
:
listen
中のWidgetが再ビルドされるaddListener(VoidCallback listeners)
:外部からカスタムリスナーを登録removeListener(VoidCallback listeners)
:登録したリスナーを解除dispose()
:クリーンアップ処理(ChangeNotifierProvider
が自動で呼ぶことが多い)Provider<T>
Provider.of<T>(context)
で取り出せるようにする箱Provider<T>(
create: (context) => Tのインスタンス,
child: Widget,
)
ChangeNotifierProvider<T extends ChangeNotifier>
ChangeNotifier
を継承したクラスを提供し、変更通知に対応ViewModel
を使った状態管理のためのProvider
ChangeNotifierProvider<T>(
create: (context) => Tのインスタンス,
child: Widget,
)
MultiProvider
Provider
を複数まとめて登録MultiProvider(
providers: [
ChangeNotifierProvider(create: (_) => ViewModelA()),
Provider(create: (_) => ServiceB()),
],
child: Widget,
)
Provider.of<T>(context, {listen = true})
T
を取得するT
型のインスタンスProvider.of<T>(context, listen: true/false)
listen
true
:値が変わるとこのWidgetも再ビルドされるfalse
:単発で値を参照するのみcontext.read<T>()
listen
しないで値を取得するT
型のインスタンスProvider.of<T>(context, listen: false)
の糖衣構文context.watch<T>
listen
する値を取得するT
型のインスタンスProvider.of<T>(context, listen: true)
の糖衣構文T
全体を監視するため、T
内のどのフィールドが変わっても再ビルドされるcontext.select<T, R>(R selector(T value))
R
型(特定の値)context.select<T, R>(
(value) => value.someField
)
T
の中から特定の値R
(someField
)だけを取り出して監視する
T
:Provider
で流している型R
:取り出したいフィールドや計算結果の型(戻り値の型)someField
が変化した時だけ再ビルドされるSelector<T, R>
Consumer
とselect
の組み合わせlisten
させるSelector<T, R>(
selector: (context, value) => value.someField,
builder: (context, field, child) {
return Widget;
},
)
Consumer<T>
listen
させる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),
),
),
);
}
}
ChangeNotifierProvider
でMyModel
を提供Consumer<MyModel>
でnotifyListeners()
に反応してUI更新context.read<Mymodel>
で状態を操作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),
),
);
}
}