状態管理の要点はその状態に影響を受けるWidgetのみが状態変化に対する処理を行えるように効率化することです。
InheritedWidget
Flutter自身を構成するWidgetの一つ。Widgetツリーの配下に効率的に情報を伝える仕組みを提供します。

import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(
key: null,
child: Scaffold(
appBar: AppBar(
title: Text("Inherited Widget Sample"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
WidgetNumText(),
WidgetCenterText(
key: null,
),
],
),
),
floatingActionButton: WidgetIncrementBtn(),
),
),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({required Key? key, required this.child}) : super(key: key);
final Widget child;
@override
_MyHomePageState createState() => _MyHomePageState();
static _MyHomePageState of(BuildContext context, {bool rebuild = true}) {
return rebuild
? (context.dependOnInheritedWidgetOfExactType<_InheritedWidget>()
as _InheritedWidget)
.data
: (context
.getElementForInheritedWidgetOfExactType<_InheritedWidget>()!
.widget as _InheritedWidget)
.data;
}
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return _InheritedWidget(
child: widget.child,
data: this,
);
}
}
class WidgetIncrementButton extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _MyHomePageState state = MyHomePage.of(context, rebuild: false);
return FloatingActionButton(
onPressed: () => state._incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
class _InheritedWidget extends InheritedWidget {
_InheritedWidget({
Key? key,
required Widget child,
required this.data,
}) : super(key: key, child: child);
final _MyHomePageState data;
@override
bool updateShouldNotify(InheritedWidget oldWidget) => true;
}
class WidgetNumText extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _MyHomePageState state = MyHomePage.of(context);
return Text(
'${state._counter}',
style: Theme.of(context).textTheme.headline4,
);
}
}
class WidgetIncrementBtn extends StatelessWidget {
@override
Widget build(BuildContext context) {
final _MyHomePageState state = MyHomePage.of(context, rebuild: false);
return FloatingActionButton(
onPressed: () => state._incrementCounter(),
tooltip: 'Increment',
child: Icon(Icons.add),
);
}
}
class WidgetCenterText extends StatelessWidget {
const WidgetCenterText({required Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return Text('You have pushed the button this many times:');
}
}
Memo
Shader compilation errorが出たら
エミュレーターからアプリを消してflutter cleanする
Provider
InheritedWidgetのラッパークラスで状態管理とDI機能を提供します。
StateNotifer
状態管理パッケージでProviderをベースに作られている。同じ作者。