作者: | 来源:互联网 | 2023-08-25 18:16
引言InheritedWidget,flutter中非常重要的一个功能组件。比如我们在应用的根widget中通过InheritedWidget共享了一个数据,那么我们
引言
InheritedWidget,flutter中非常重要的一个功能组件。比如我们在应用的根 widget 中通过InheritedWidget共享了一个数据,那么我们便可以在任意子 widget 中来获取该共享的数据。
# didChangeDependencies
说到 InheritedWidget ,我们不得不聊聊 state 对象中的 didChangeDependencies
方法。当子控件依赖使用了父控件中的 InheritedWidget,比如主题、locale(语言)等发生变化时,依赖其的子 widget 的didChangeDependencies
方法将会被调用。
一般来说,子 widget 很少会重写此方法,因为在依赖改变后 framework 也都会调用build()方法。但是,如果你需要在依赖改变后执行一些昂贵的操作,比如网络请求,这时最好的方式就是在此方法中执行,这样可以避免每次build()都执行这些昂贵操作。
重点: 如子控件build 方法中没有使用 InheritedShareWidget 的数据,那么它的didChangeDependencies
将不会被调用
如何使用?
我们简单用一个 count 自增的例子来记录 InheritedWidget 的使用:
- 新建 InheritedShareWidget 继承 InheritedWidget 作为共享数据源,以其为父节点提供子节点数据
import 'package:flutter/material.dart';
class InheritedShareWidget extends InheritedWidget {
//用于共享的数据
final int data;
InheritedShareWidget({this.data, Widget child}) : super(child: child);
//定义便捷方法,方便子控件获取共享数据
static InheritedShareWidget of(BuildContext context) {
///当子控件依赖使用了我们的数据源时,数据变动会触发子控件中的 didChangeDependencies 方法
return context.dependOnInheritedWidgetOfExactType();
///不会触发子控件中的 didChangeDependencies 方法
// return context.getElementForInheritedWidgetOfExactType().widget;
}
@override
bool updateShouldNotify(covariant InheritedShareWidget oldWidget) {
//返回true时,才会通知子控件
return oldWidget.data != this.data;
}
}
- 子节点中如何获取共享数据?
class TestShareChildWidget extends StatefulWidget {
const TestShareChildWidget({Key key}) : super(key: key);
@override
_TestShareChildWidgetState createState() => _TestShareChildWidgetState();
}
class _TestShareChildWidgetState extends State {
@override
void didChangeDependencies() {
///如build 方法中没有使用 InheritedShareWidget 的数据,那么它的didChangeDependencies()将不会被调用
super.didChangeDependencies();
print("enter didChangeDependencies");
}
@override
Widget build(BuildContext context) {
print("enter child build");
//获取Inherited的共享数据:
final data = InheritedShareWidget.of(context).data.toString();
return Text(data);
}
}
- 两者通过父子嵌套的关系联系在一起:
class _TestInheritedWidgetState extends State {
int count = 0;
@override
Widget build(BuildContext context) {
return Center(
child: InheritedShareWidget(
data: count,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
TestShareChildWidget(),
RaisedButton(
child: Text('add'),
onPressed: () {
setState(() {
++count;
});
})
],
),
),
);
}
}