1.直接子Widgetに引数として渡す
最も簡単な方法の一つは、子ウィジェット(データを渡したい側)のコンストラクタを通じて直接データを渡す方法です。
これは、特に小規模なアプリケーションや単純なウィジェットツリーの場合に有効です。
Dart
//⓸データを受取りたい側のクラス
class CustomWidget extends StatelessWidget {
final List<Map<String, dynamic>> cates; //⓹受取りたいデータの器
//⓺ここでコンストラクタの引数として直接データを渡す
const CustomWidget({Key? key, required this.cates}) : super(key: key);
@override
Widget build(BuildContext context) {
return ListView.builder(
itemCount: cates.length, //←⓻ここで利用できる
itemBuilder: (context, index) {
return ListTile(
title: Text(cates[index]['description']), //←⓻ここで利用できる
);
},
);
}
}
//⓵データを渡したい側のクラス
class TabBarPageState extends State<TabBarPage> {
List<Map<String, dynamic>> cates = []; //⓶渡したいデータ
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Categories")),
body: CustomWidget(cates: cates), //←⓷ここで渡す
);
}
}
2.InheritedWidgetを使用する
上記以外に、InheritedWidget
を使用する方法があります。
InheritedWidget は、ウィジェットツリーを通じてデータを効率的に渡すために設計されています。
Dart
//データ中継用クラス(再利用可能(同じデータ型の場合))
//・クラス名は任意
//・InheritedWidget継承(extends InheritedWidget)必須
class CatesProvider extends InheritedWidget {
//中継対象となるデータ型定義
final List<Map<String, dynamic>> cates; // ← ここで宣言する
//中継用コンストラクタ
const CatesProvider({
Key? key, //キー(必須)
required this.cates, // ← ここで中継データを設定する
required Widget child, //子ウィジェット(必須)
}) : super(key: key, child: child);
//探索用メソッド(必須)
static CatesProvider? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<CatesProvider>();
}
//提供データ更新メソッド(必須)
//・メソッド名は固定
@override
bool updateShouldNotify(CatesProvider oldWidget) {
return oldWidget.cates != cates; // ← ここで比較する
}
}
//データを渡したい側(親ウィジェット側)のクラス
class TabBarPageState extends State<TabBarPage> {
List<Map<String, dynamic>> cates = []; // ← 源泉となるデータ
@override
Widget build(BuildContext context) {
//データ中継用クラス(ThisEx: 'CatesProvider')
//のラップ範囲(スコープ(ThisEx: 'Scaffold'含む))に
//データ(ThisEx: 'cates')を伝播する
//(故に子ウィジェットに(データ(ThisEx: 'cates')が伝播される)
return CatesProvider(
cates: cates, // ← 伝播するデータ
child: Scaffold(
appBar: AppBar(title: Text("Categories")),
body: CustomWidget(), // ← データを貰いたい側(子ウィジェット)のクラス
// (重要)引数無し!!
),
);
}
}
//データを貰いたい側(子ウィジェット)のクラス
//(いわゆる'カスタムウィジェット'と言われているもの)
class CustomWidget extends StatelessWidget {
@override
Widget build(BuildContext context) {
//データ中継用クラス(ThisEx: 'CatesProvider')からデータ受取
final cates = CatesProvider.of(context)?.cates ?? []; //←データを受取る
return ListView.builder(
itemCount: cates.length, //←ここでデータを利用する
itemBuilder: (context, index) {
return ListTile(
title: Text(cates[index]['description']), //←ここでデータを利用する
);
},
);
}
}
3.状態管理ライブラリを使用する
大規模なアプリケーションや、より複雑な状態管理が必要な場合、
・Provider
・Riverpd
・Bloc
等の状態管理ライブラリを使用すると便利です。
これらのライブラリはデータの共有と更新を簡単に行え、コードの保守性を向上させます。
こちらについては、別記事を参照願います。