当前位置: 首页 > news >正文

宝武马钢集团公司招聘网站违禁网站用什么浏览器

宝武马钢集团公司招聘网站,违禁网站用什么浏览器,广州网络推广服务,网站中了木马了怎么办InheritedWidget的核心是保存值和保存使用这个值的widget,通过对比值的变化,来决定是否要通知那些使用了这个值的widget更新自身。 1 updateShouldNotify和notifyClients InheritedWidget通过updateShouldNotify函数控制依赖其的子组件是否在Inherited…

 InheritedWidget的核心是保存值和保存使用这个值的widget,通过对比值的变化,来决定是否要通知那些使用了这个值的widget更新自身。

1 updateShouldNotify和notifyClients

InheritedWidget通过updateShouldNotify函数控制依赖其的子组件是否在InheritedWidget变化时会被重建:如果updateShouldNotify返回true,InheritedWidget变化时子组件的build会被调用,反之则不会。

InheritedElement中的updated方法:

@override
void updated(InheritedWidget oldWidget) {if (widget.updateShouldNotify(oldWidget))super.updated(oldWidget);
}

InheritedElement继承于ProxyElement,而ProxyElement的updated实现为:

@protectedvoid updated(covariant ProxyWidget oldWidget) {notifyClients(oldWidget);}

而InheritedElement的notifyClients实现是遍历_dependents中依赖自己的widget,然后调用它的didChangeDependencies进行变化通知:

  @overridevoid notifyClients(InheritedWidget oldWidget) {assert(_debugCheckOwnerBuildTargetExists('notifyClients'));for (final Element dependent in _dependents.keys) {assert(() {// check that it really is our descendantElement? ancestor = dependent._parent;while (ancestor != this && ancestor != null) {ancestor = ancestor._parent;}return ancestor == this;}());// check that it really depends on usassert(dependent._dependencies!.contains(this));notifyDependent(oldWidget, dependent);}}@protectedvoid notifyDependent(covariant InheritedWidget oldWidget, Element dependent) {dependent.didChangeDependencies();}
Element的didChangeDependencies源码如下:void didChangeDependencies() {assert(_active); // otherwise markNeedsBuild is a no-opassert(_debugCheckOwnerBuildTargetExists('didChangeDependencies'));markNeedsBuild();
}

可以看到,InheritedWidget变化时,如果updateShouldNotify是true,会通过notifyClients调用子组件的didChangeDependencies函数,从而调用markNeedsBuild,将本Element加入_dirtyElements列表中。大家都知道,_dirtyElements中保存的是需要重建的Element,会在下一帧时被rebuild,因此在下一帧子组件会被重建(rebuild)。

2 InheritedWidget的传递

InheritedWidget能用于让用户快速从子组件获取,这是怎么实现的呢?

其实Flutter Framework也是将InheritedWidget一层层传递下来的,只不过由于Framework层自行处理了,因此这个过程对于我们是透明的。我们现在来梳理下InheritedWidget传递的过程。

Element中,有一个map:_inheritedWidgets。保存了所有上级节点中的InheritedElement。其源码如下:

Map<Type, InheritedElement> _inheritedWidgets;

其中,key中Type是InheritedWidget的子类,value是InheritedElement。为什么这里value保存的是InheritedElement而不是InheritedWidget呢?由以前的文章可以知道Element中保存着对应Widget的引用,因此可以通过InheritedElement获取对应的InheritedWidget。而且Widget在上级Widget重建时会被重建,因此保存InheritedElement更合适。

在普通的Element中,_inheritedWidgets会直接复制其父组件中_inheritedWidgets的值,其源码如下:

void _updateInheritance() {assert(_active);_inheritedWidgets = _parent?._inheritedWidgets;
}

而在InheritedElement中,_inheritedWidgets会首先复制其父组件中_inheritedWidgets的值,然后将自己添加进列表,其源码如下:

@override
void _updateInheritance() {assert(_active);final Map<Type, InheritedElement> incomingWidgets = _parent?._inheritedWidgets;if (incomingWidgets != null)_inheritedWidgets = HashMap<Type, InheritedElement>.from(incomingWidgets);else_inheritedWidgets = HashMap<Type, InheritedElement>();_inheritedWidgets[widget.runtimeType] = this;
}

由此可以看出,InheritedElement就是这样一层层传递下来的。_inheritedWidgets赋值流程如下:

由该流程图可以看出,_inheritedWidgets在Element被加入Element Tree时就已经被赋值,因此其在子组件的build函数中是可以访问得到的。

3 InheritedWidget的获取及注册依赖

我们已经知道了InheritedElement会传递到下级组件中,那怎么获取它呢?Flutter提供了专门获取某个InheritedWidget类型的函数dependOnInheritedWidgetOfExactType.其源码如下:

@override
T dependOnInheritedWidgetOfExactType<T extends InheritedWidget>({Object aspect}) {assert(_debugCheckStateIsActiveForAncestorLookup());final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[T];if (ancestor != null) {assert(ancestor is InheritedElement);return dependOnInheritedElement(ancestor, aspect: aspect) as T;}_hadUnsatisfiedDependencies = true;return null;
}

由第三行可以看出,此函数会从_inheritedWidgets中寻找对应的InheritedElement,并返回其InheritedWidget。

除了dependOnInheritedWidgetOfExactType,Flutter还提供了另一个专门获取某个InheritedWidget类型的函数:getElementForInheritedWidgetOfExactType。其源码如下:

@override
InheritedElement getElementForInheritedWidgetOfExactType<T extends InheritedWidget>() {assert(_debugCheckStateIsActiveForAncestorLookup());final InheritedElement ancestor = _inheritedWidgets == null ? null : _inheritedWidgets[T];return ancestor;
}

对比其与dependOnInheritedWidgetOfExactType源码,可以看到dependOnInheritedWidgetOfExactType多了dependOnInheritedElement函数的调用,该函数用于创建InheritedWidget和调用dependOnInheritedWidgetOfExactType的组件的依赖关系。其有两个步骤:

  • 将依赖的InheritedElement加入本Element的_dependencies列表,该列表中保存了本Element所有依赖的InheritedElement.
  • 将本Element加入依赖的InheritedElement的_dependents map,该列表中保存了所有依赖该InheritedElement的Element。

如果使用的是dependOnInheritedWidgetOfExactType,则当被依赖的InheritedWidget被更新时,依赖的子组件会被rebuild;而使用的是getElementForInheritedWidgetOfExactType时,由于不会建立相应的依赖关系,InheritedWidget被更新时,依赖的子组件不会被rebuild。

4 主动调用dependOnInheritedWidgetOfExactType

 子组件需要通过调用dependOnInheritedWidgetOfExactType来获取InheritedWidget,并且将自己加入该InheritedWidget的依赖中。方便起见,一般会在InheritedWidget子类中实现of方法:

class ShareDataWidget extends InheritedWidget {ShareDataWidget({@required this.data,Widget child}) :super(child: child);final int data; //需要在子树中共享的数据,保存点击次数//定义一个便捷方法,方便子树中的widget获取共享数据static ShareDataWidget of(BuildContext context) {return context.dependOnInheritedWidgetOfExactType<ShareDataWidget>();}//该回调决定当data发生变化时,是否通知子树中依赖data的Widget@overridebool updateShouldNotify(ShareDataWidget old) {//如果返回true,则子树中依赖(build函数中有调用)本widget//的子widget的`state.didChangeDependencies`会被调用return old.data != data;}
}class _TestWidget extends StatefulWidget {@override__TestWidgetState createState() => new __TestWidgetState();
}class __TestWidgetState extends State<_TestWidget> {@overrideWidget build(BuildContext context) {print("__TestWidgetState build");//使用InheritedWidget中的共享数据return Text(ShareDataWidget.of(context).data.toString());// return Text("tex");}@overridevoid didChangeDependencies() {super.didChangeDependencies();//父或祖先widget中的InheritedWidget改变(updateShouldNotify返回true)时会被调用。//如果build中没有依赖InheritedWidget,则此回调不会被调用。print("Dependencies change");}
}

参考:

Flutter框架分析 -InheritedWidget - 知乎

http://www.hkea.cn/news/20721/

相关文章:

  • 装修公司全包项目seo搜索引擎实训心得体会
  • 爱站网是干什么的长沙关键词排名首页
  • wordpress 教垜四川seo推广公司
  • 东莞市阳光网青岛seo服务
  • 网站弹窗在中间位置企业培训师
  • 整站下载器 安卓版域名解析查询站长工具
  • 跨境自建站模板seo推广是做什么
  • 网站建设与网页设计报告网络营销师报名入口
  • 生成前端页面的网站东莞网络营销全网推广
  • 网站及单位网站建设情况免费男女打扑克的软件
  • 公司有网站有什么好处网上开店如何推广自己的网店
  • 海口网站建设策划关键词排名优化工具有用吗
  • 请问哪里可以做网站汕头seo
  • 访问国外网站速度慢苏州关键词seo排名
  • 做网站备案照片的要求谷歌seo教程
  • wordpress站点全屏新站如何让百度快速收录
  • wordpress 会议 主题推广排名seo
  • 源码开发网站建设sem与seo的区别
  • 如何查网站的空间防恶意点击软件
  • 单位网站建设收费标准互联网推广引流
  • 网站有中文源码加英文怎么做关键词歌词完整版
  • 建设网站企业银行做网站的平台
  • 如何进行网站建设分析网站推广app软件
  • 做ppt的软件模板下载网站网站服务公司
  • 网站icp备案认证怎么做谷歌网页版入口在线
  • 高安网站建设艺考培训
  • 主流的网站开发技术百度推广后台管理
  • 传奇网站模板免费下载优化网络搜索引擎
  • 提升学历报考什么专业比较好seosem顾问
  • 做违法网站犯法吗推广费用一般多少钱