当前位置:网站首页>Shutter: about inheritedwidget
Shutter: about inheritedwidget
2022-07-03 12:01:00 【J_ D_ Chi】
Write it at the front
InheritedWidget Is a component for data sharing , Its data transmission direction is from top to bottom , So when we put data in it , When there is data change , Those who depend on it Widget Data changes can be obtained .
Content
abstract class InheritedWidget extends ProxyWidget {
const InheritedWidget({ Key? key, required Widget child })
: super(key: key, child: child);
@override
InheritedElement createElement() => InheritedElement(this);
@protected
bool updateShouldNotify(covariant InheritedWidget oldWidget);
}
updateShouldNotify() Method is used to make Framework Judge whether to remind those who depend on this InheritedWidget Of Widget.
InheritedWidget Is an abstract class , It means that we must realize it , Here we use 《Flutter actual combat 》 Examples in a book 7.2 Data sharing (InheritedWidget) As an expression of :
class ShareDataWidget extends InheritedWidget {
ShareDataWidget({
@required this.data,
Widget child
}) :super(child: child);
final int data; // Data that needs to be shared in the subtree , Save hits
// Define a convenient method , In convenience subtree widget Get shared data
static ShareDataWidget of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
}
// The callback determines when data When something changes , Whether to notify dependency in subtree data Of Widget
@override
bool updateShouldNotify(ShareDataWidget old) {
// If you return true, Dependency in subtree (build Call in function ) Ben widget
// The son of widget Of `state.didChangeDependencies` Will be called
return old.data != data;
}
}
class _TestWidget extends StatefulWidget {
@override
__TestWidgetState createState() => new __TestWidgetState();
}
class __TestWidgetState extends State<_TestWidget> {
@override
Widget build(BuildContext context) {
// Use InheritedWidget Shared data in
return Text(ShareDataWidget
.of(context)
.data
.toString());
}
@override
void didChangeDependencies() {
super.didChangeDependencies();
// Father or ancestor widget Medium InheritedWidget change (updateShouldNotify return true) Will be called .
// If build No dependency in InheritedWidget, Then this callback will not be called .
print("Dependencies change");
}
}
class InheritedWidgetTestRoute extends StatefulWidget {
@override
_InheritedWidgetTestRouteState createState() => new _InheritedWidgetTestRouteState();
}
class _InheritedWidgetTestRouteState extends State<InheritedWidgetTestRoute> {
int count = 0;
@override
Widget build(BuildContext context) {
return Center(
child: ShareDataWidget( // Use ShareDataWidget
data: count,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(bottom: 20.0),
child: _TestWidget(),// Son widget The dependence ShareDataWidget
),
RaisedButton(
child: Text("Increment"),
// Every click , take count Self increasing , And then again build,ShareDataWidget Of data Will be updated
onPressed: () => setState(() => ++count),
)
],
),
),
);
}
}
When we click the button , And then call setState() Methods , When the next frame comes , Will call InheritedWidgetTestRoute Conduct rebuild, Then call it recursively child Of update() Method .
By inheritance :
Will call first ProxyElement Of update() Method , It's called in updated() Method :
abstract class ProxyElement extends ComponentElement {
@override
void update(ProxyWidget newWidget) {
final ProxyWidget oldWidget = widget;
assert(widget != null);
assert(widget != newWidget);
super.update(newWidget);
assert(widget == newWidget);
updated(oldWidget);
_dirty = true;
rebuild();
}
@protected
void updated(covariant ProxyWidget oldWidget) {
notifyClients(oldWidget);
}
}
InheritedElement Rewrote updated() Method , Here we use our updateShouldNotify() Method , You can know that the whole process is to traverse a Map Type of _dependents, Rely on the inside Element Call their didChangeDependencies Method .
class InheritedElement extends ProxyElement {
final Map<Element, Object?> _dependents = HashMap<Element, Object?>();
...
@override
void updated(InheritedWidget oldWidget) {
if (widget.updateShouldNotify(oldWidget))
super.updated(oldWidget);
}
@override
void notifyClients(InheritedWidget oldWidget) {
...
for (final Element dependent in _dependents.keys) {
...
notifyDependent(oldWidget, dependent);
}
}
...
@protected
void notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {
dependent.didChangeDependencies();
}
}
So where do you add these dependencies ?
abstract class Element extends DiagnosticableTree implements BuildContext {
...
@override
T? dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object? aspect}) {
...
final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T];
if (ancestor != null) {
return dependOnInheritedElement(ancestor, aspect: aspect) as T;
}
_hadUnsatisfiedDependencies = true;
return null;
}
@override
InheritedWidget dependOnInheritedElement(InheritedElement ancestor, { Object? aspect }) {
...
_dependencies ??= HashSet<InheritedElement>();
_dependencies!.add(ancestor);
// there this Is the current Element example
ancestor.updateDependencies(this, aspect);
return ancestor.widget;
}
}
We are Element You can see in the class , Called before us dependOnInheritedWidgetOfExactType() In the method , Will be called to dependOnInheritedElement() Method , It will call our current ShareDataWidget The corresponding InheritedElement Of updateDependencies() Method .
class InheritedElement extends ProxyElement {
...
@protected
void updateDependencies(Element dependent, Object? aspect) {
setDependencies(dependent, null);
}
@protected
void setDependencies(Element dependent, Object? value) {
_dependents[dependent] = value;
}
}
That is to say, when one of us Widget By calling ShareDataWidget Of of When using static methods , Just register yourself . In this way, subsequent updates can be notified .
So use dependOnInheritedWidgetOfExactType() Method we can see that this will register dependencies , So when the data is updated , The children of these dependencies Widget Will be called to didChangeDependencies() Method , Then they all need to be done build().
If we just want ShareDataWidget The data of , I don't want to didChangeDependencies() Called , Then use another method getElementForInheritedWidgetOfExactType<T extends InheritedWidget>(), hold ShareDataWidget Of of The method is rewritten as follows :
static ShareDataWidget of(BuildContext context) {
//return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();
return context.getElementForInheritedWidgetOfExactType<ShareDataWidget>().widget;
}
abstract class Element extends DiagnosticableTree implements BuildContext {
...
@override
InheritedElement? getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() {
...
final InheritedElement? ancestor = _inheritedWidgets == null ? null : _inheritedWidgets![T];
return ancestor;
}
...
}
getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() Method heel dependOnInheritedWidgetOfExactType() The difference is that there is no registration relationship .
summary
- Realization
InheritedWidget, stayupdateShouldNotify()It is written in the method that what conditions will trigger the reminder - adopt
context.dependOnInheritedWidgetOfExactType()Method , Both let son Child Access to data , At the same time, it also plays a role Child Their own Element Sign up toInheritedWidgetin . - When data changes , Trigger to
InheritedWidgetImplementation classupdate()Method time , It will traverse the previously registered Element list , And then call theirdidChangeDependencies()Method , next Framework Would callbuildMethod .
边栏推荐
- Keepalived中Master和Backup角色选举策略
- Sheet1$. Output [excel source output] Error in column [xxx]. The returned column status is: "the text is truncated, or one or more characters have no matches in the target code page.".
- STL教程9-容器元素深拷贝和浅拷贝问题
- During FTP login, the error "530 login incorrect.login failed" is reported
- 错排问题 (抽奖,发邮件)
- Nestjs configuration service, configuring cookies and sessions
- OpenStack中的测试分类
- Qt+vtk+occt reading iges/step model
- php 获取文件夹下面的文件列表和文件夹列表
- PHP导出word方法(一mht)
猜你喜欢

836. Merge sets (day 63) and search sets

Introduction to the implementation principle of rxjs observable filter operator

Colleagues wrote a responsibility chain model, with countless bugs

Download address and installation tutorial of vs2015

Qt OpenGL 旋转、平移、缩放

Vulnhub pyexp

Vulnhub's cereal

量化计算调研

Vulnhub geminiinc
![[official MySQL document] deadlock](/img/2d/04e97d696f20c2524701888ea9cd10.png)
[official MySQL document] deadlock
随机推荐
解决msvcp120d.dll和msvcr120d.dll缺失
The tutor put forward 20 pieces of advice to help graduate students successfully complete their studies: first, don't plan to take a vacation
Hongmeng third training (project training)
Solution to the second weekly test of ACM intensive training of Hunan Institute of technology in 2022
《剑指offer 04》二维数组查找
vulnhub之Ripper
Why can't my MySQL container start
Uniapp implementation Click to load more
PHP導出word方法(一mht)
Differences between MySQL Union and union all
Vulnhub's cereal
Optimize interface performance
网络通讯之Socket-Tcp(一)
简单工厂和工厂方法模式
PHP导出word方法(一mht)
previous permutation lintcode51
Is BigDecimal safe to calculate the amount? Look at these five pits~~
"Jianzhi offer 04" two-dimensional array search
OpenStack中的测试分类
Vulnhub narak