InheritedWidget
创建继承自 InheritedWidget
的类
class ShareWidget extends InheritedWidget {
final int counter;
ShareWidget({required this.counter, required Widget child}): super(child: child);
static ShareWidget? of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType();
}
@override
bool updateShouldNotify(covariant ShareWidget oldWidget) {
return oldWidget.counter != counter;
}
}
需要共享的widget
body: ShareWidget(
counter: _counter,
child: Column(
children: [
ShowData(),
],
),
),
class ShowData extends StatefulWidget {
@override
State createState() => _ShowDataState();
}
class _ShowDataState extends State {
@override
void didChangeDependencies() {
super.didChangeDependencies();
print("计数改变了");
}
@override
Widget build(BuildContext context) {
final int? num = ShareWidget.of(context)?.counter;
return Card(
color: Colors.blue,
child: Text("当前计数 $num"),
);
}
}
Provider
导入 provider 库
- 创建需要共享的数据
class CounterViewModel extends ChangeNotifier {
int _counter = 100;
int get counter => _counter;
set counter(int value) {
_counter = value;
notifyListeners();
}
}
- 在应用程序的顶层创建 ChangeNotifierProvider
void main() {
runApp(ChangeNotifierProvider(
create: (context) => CounterViewModel(), child: MyApp()));
}
多个 viewmodel
void main() {
runApp(MultiProvider(providers: providers, child: MyApp()));
}
List providers = [
ChangeNotifierProvider(create: (context) => CounterViewModel()),
ChangeNotifierProvider(create: (context) => UserViewModel())
];
- 使用共享的数据
区别:
-
Provider.of
: 当Provider
中的数据发生改变时,Provider
所在的widget
整个build
方法都会重新构建 -
Consumer
:当Provider
中的数据发生改变时,只会重新执行Consumer
中的builder
。builder
中的child
参数防止重复构建 widget。 -
Selector
:
--selector
方法,对原有的数据进行转换。
--shouldRebuild
方法,是否需要重新构建。
class ShowData extends StatefulWidget {
@override
State createState() => _ShowDataState();
}
class _ShowDataState extends State {
@override
Widget build(BuildContext context) {
return Card(
color: Colors.blue,
child: Consumer(builder: (context, viewmodel, child) {
return Text("当前计数 ${viewmodel.counter}");
}),
);
}
/* 或者使用 Provider
@override
Widget build(BuildContext context) {
// 3.使用共享的数据
int counter = Provider.of(context).counter;
return Card(
color: Colors.blue,
child: Text("当前计数 $counter"),
);
}
*/
}
Selector2
、Selector3
、Selector4
、Selector5
、Selector6
Consumer2
、Consumer3
、Consumer4
、Consumer5
、Consumer6
child: Consumer2(
builder: (context, counterVM, userVM, child) {
return Text("当前计数 ${counterVM.counter}");
}),
- 赋值
Consumer
floatingActionButton: Consumer(
builder: (context, viewmodel, child) {
return FloatingActionButton(
child: child,
onPressed: () {
viewmodel.counter++;
},
);
},
child: Icon(Icons.add),
)
Selector
floatingActionButton: Selector(
selector: (context, viewmodel) => viewmodel,
shouldRebuild: (pre, nex) => false, // 是否需要重新构建
builder: (context, viewmodel, child) {
return FloatingActionButton(
child: child,
onPressed: () {
viewmodel.counter++;
},
);
},
child: Icon(Icons.add),
)