Flutterでは、InheritedWidgetとBuildContextを使用して、状態を簡単かつ効率的に管理できます。InheritedWidgetは、親Widgetから子Widgetに状態を伝えるための一種のコンテナであり、BuildContextは、Widgetの構築中に使用されるビルドコンテキストの一種です。この記事では、FlutterのInheritedWidgetとBuildContextを使用した状態管理について、詳しい使い方を紹介します。
InheritedWidgetとは?
InheritedWidgetは、親Widgetから子Widgetに状態を伝えるために使用されます。一般的には、ビルド中に変更されることのないデータを伝えるために使用されます。例えば、アプリのテーマやロケールなどの情報がInheritedWidgetに保存されることがあります。
InheritedWidgetは、自身を更新することはできず、新しいInheritedWidgetインスタンスを作成する必要があります。親WidgetでInheritedWidgetのインスタンスが変更されると、それに依存する子Widgetは自動的に再ビルドされます。このため、InheritedWidgetを使用すると、状態を簡単かつ効率的に管理できます。
InheritedWidgetを使用した状態管理の基本的な使い方
InheritedWidgetを使用して状態を管理するには、次の手順が必要です。
- InheritedWidgetを作成する
- InheritedWidgetを提供する親Widgetを作成する
- InheritedWidgetに依存する子Widgetを作成する
以下に、それぞれの手順について詳しく説明します。
1. InheritedWidgetを作成する
InheritedWidgetを作成するには、次の手順が必要です。
- InheritedWidgetを継承する
- InheritedWidgetに伝えたい状態を定義する
- InheritedWidgetに、状態を取得するためのメソッドを追加する
例えば、アプリのテーマを管理するInheritedWidgetを作成する場合、次のようなコードを記述することができます。
class ThemeState extends InheritedWidget {
final ThemeData themeData;
ThemeState({Key? key, required Widget child, required this.themeData})
: super(key: key, child: child);
static ThemeState? of(BuildContext context) =>
context.dependOnInheritedWidgetOfExactType<ThemeState>();
@override
bool updateShouldNotify(covariant ThemeState oldWidget) =>
oldWidget.themeData != themeData;
}
このコードでは、ThemeStateというInheritedWidgetを定義しています。themeDataというフィールドは、アプリのテーマデータを格納するために使用されます。ofメソッドは、BuildContextからThemeStateインスタンスを取得するために使用されます。updateShouldNotifyメソッドは、InheritedWidgetが更新されたかどうかを判断するために使用されます。
2. InheritedWidgetを提供する親Widgetを作成する
InheritedWidgetを提供する親Widgetを作成するには、次の手順が必要です。
- InheritedWidgetを含める
- InheritedWidgetをビルドする
例えば、アプリのルートWidgetであるMyAppWidgetが親Widgetであり、InheritedWidgetであるThemeStateを提供する場合、次のようなコードを記述することができます。
class MyAppWidget extends StatefulWidget {
const MyAppWidget({Key? key}) : super(key: key);
@override
_MyAppWidgetState createState() => _MyAppWidgetState();
}
class _MyAppWidgetState extends State<MyAppWidget> {
ThemeData _themeData = ThemeData.light();
void _toggleTheme() {
setState(() {
_themeData = _themeData == ThemeData.light()
? ThemeData.dark()
: ThemeData.light();
});
}
@override
Widget build(BuildContext context) {
return ThemeState(
themeData: _themeData,
child: MaterialApp(
title: 'My App',
home: HomePage(
onThemeToggle: _toggleTheme,
),
),
);
}
}
このコードでは、MyAppWidgetがThemeStateを提供しています。_themeDataというフィールドは、現在のテーマデータを保持するために使用されます。_toggleThemeメソッドは、テーマを切り替えるために使用されます。buildメソッドでは、ThemeStateを使用して、_themeDataを提供し、childには、アプリのルートWidgetであるMaterialAppを設定しています。
3. InheritedWidgetに依存する子Widgetを作成する
InheritedWidgetに依存する子Widgetを作成するには、次の手順が必要です。
- InheritedWidgetを使用して状態を取得する
- 状態に基づいてWidgetを構築する
例えば、アプリのホームページであるHomePageWidgetが、テーマを切り替えるためのボタンを提供する場合、次のようなコードを記述することができます。
class HomePage extends StatelessWidget {
final VoidCallback onThemeToggle;
const HomePage({Key? key, required this.onThemeToggle}) : super(key: key);
@override
Widget build(BuildContext context) {
final themeData = ThemeState.of(context)!.themeData;
return Scaffold(
appBar: AppBar(
title: Text('My App'),
),
body: Center(
child: Text(
'Hello, World!',
style: TextStyle(
fontSize: 24,
fontWeight: FontWeight.bold,
color: themeData.primaryColor,
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: onThemeToggle,
child: Icon(Icons.color_lens),
),
);
}
}
このコードでは、HomePageWidgetがThemeStateに依存しています。ofメソッドを使用して、現在のテーマデータを取得しています。テーマデータを使用して、テキストの色を設定しています。また、floatingActionButtonは、テーマを切り替えるためのボタンであり、onThemeToggleコールバックを呼び出して、MyAppWidgetで定義された_toggleThemeメソッドを呼び出します。
InheritedWidgetを使用して状態を管理する方法について、詳細に説明しました。InheritedWidgetを使用すると、Flutterの状態管理についての理解が深まり、アプリケーションのパフォーマンスが向上する可能性があります。しかし、InheritedWidgetは、複雑なアプリケーションでは十分に使いやすいとは限りません。その場合は、別の状態管理の方法を検討する必要があります。
InheritedWidget以外の状態管理の方法は以下の記事および、記事内のリンクページにそれぞれの詳しい使い方の説明を記載していますので、参考にしてみて下さい。