InheritedWidget在处理父子组件数据共享的问题上有着天然的优势,虽然有系统总线这种类似的方法,下面我加了个例子来说明这个组件该如何用。一个简单的计数器奉上。
一:如何自定义共享的数据
首先自定义一个类继承至InheritedWidget,我们命名为ShareDataWidget,该类定义你想保存的数据类型,这里我定义了个int类型的数据来实现数据共享,如果你想保存更复杂的类型可以自行修改。
/// 需要在组件树中共享的数据
final int data;
二:数据有了怎么保存的数据
我们这里定义一个便捷的方法,一个静态的方法of来处理数据,该方法返回一个InheritedWidget的一个子类,来告诉编译器来保存这个子类的数据
static ShareDataWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
}
三:是否需要更新通知,数据更新了,是否通知观察者需要更新数据
@override
bool updateShouldNotify(covariant ShareDataWidget oldWidget) {
// TODO: implement updateShouldNotify
return oldWidget.data != data;
}
完整代码:
import 'package:flutter/material.dart';
class ShareDataWidget extends InheritedWidget {
const ShareDataWidget({required this.data, required Widget child})
: super(child: child);
/// 需要在组件树中共享的数据
final int data;
static ShareDataWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
}
@override
bool updateShouldNotify(covariant ShareDataWidget oldWidget) {
// TODO: implement updateShouldNotify
return oldWidget.data != data;
}
}
四:具体用法
说了这么多,现在该说说怎么用了,既然它能使子widget用到的共享数据更新,那我们来搞一个子widget出来,当然为了小伙伴的阅读成本,这个例子也很简单就是一个文本显示的widget:
class TestWidget extends StatefulWidget {
const TestWidget({Key? key}) : super(key: key);
@override
State<TestWidget> createState() => _TestWidgetState();
}
class _TestWidgetState extends State<TestWidget> {
@override
Widget build(BuildContext context) {
/// 这里拿到了ShareDataWidget里面保存的数据,表示子widget使用了共享数据了,改数据更新了会调用下面的方法
return Text(ShareDataWidget.of(context)!.data.toString());
}
@override
void didChangeDependencies() {
// TODO: implement didChangeDependencies
super.didChangeDependencies();
print("dependencies changes");
}
}
另外只有文本显示肯定不行,这里得有个按钮什么的角色出场来改变这个全局的数据,与其他的widget一样,ShareDataWidget用法类似,
class TestInheritedWidget extends StatefulWidget {
const TestInheritedWidget({Key? key}) : super(key: key);
@override
State<TestInheritedWidget> createState() => _TestInheritedWidgetState();
}
class _TestInheritedWidgetState extends State<TestInheritedWidget> {
int count = 0;
@override
Widget build(BuildContext context) {
return Center(
child: ShareDataWidget(
data: count,
child: Column(
children: [
TestWidget(),
ElevatedButton(
onPressed: () {
++count;
setState(() {});
},
child: Text("Increment"))
],
),
),
);
}
}