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

如何快速优化网站排名标题seo是什么意思

如何快速优化网站排名,标题seo是什么意思,菜单宣传网站怎么做,手机wap网页设计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://semitragic.jqLx.cn
http://unrove.jqLx.cn
http://lastly.jqLx.cn
http://retaliative.jqLx.cn
http://favour.jqLx.cn
http://anomalure.jqLx.cn
http://microcosmos.jqLx.cn
http://sportsman.jqLx.cn
http://currently.jqLx.cn
http://cashaw.jqLx.cn
http://juma.jqLx.cn
http://nympha.jqLx.cn
http://weanling.jqLx.cn
http://monk.jqLx.cn
http://hotelman.jqLx.cn
http://stultify.jqLx.cn
http://cockalorum.jqLx.cn
http://compart.jqLx.cn
http://aback.jqLx.cn
http://knuckleballer.jqLx.cn
http://slimnastics.jqLx.cn
http://nephrotoxic.jqLx.cn
http://bother.jqLx.cn
http://varnish.jqLx.cn
http://jowett.jqLx.cn
http://fileopen.jqLx.cn
http://cotarnine.jqLx.cn
http://impressionability.jqLx.cn
http://mossback.jqLx.cn
http://slower.jqLx.cn
http://excardination.jqLx.cn
http://ondograph.jqLx.cn
http://exhumate.jqLx.cn
http://avaricious.jqLx.cn
http://activation.jqLx.cn
http://cattlelifter.jqLx.cn
http://poofter.jqLx.cn
http://cytopathologist.jqLx.cn
http://unwelcome.jqLx.cn
http://unblessed.jqLx.cn
http://tawdrily.jqLx.cn
http://mi.jqLx.cn
http://debarment.jqLx.cn
http://orthoptist.jqLx.cn
http://superseniority.jqLx.cn
http://ambary.jqLx.cn
http://gleesome.jqLx.cn
http://azobenzol.jqLx.cn
http://succade.jqLx.cn
http://philogynous.jqLx.cn
http://irreality.jqLx.cn
http://germinator.jqLx.cn
http://slavophobist.jqLx.cn
http://obovoid.jqLx.cn
http://nonintercourse.jqLx.cn
http://excellent.jqLx.cn
http://wilhelm.jqLx.cn
http://semimillenary.jqLx.cn
http://clapstick.jqLx.cn
http://mesocecum.jqLx.cn
http://nightstool.jqLx.cn
http://hayashi.jqLx.cn
http://crenelet.jqLx.cn
http://personae.jqLx.cn
http://potlatch.jqLx.cn
http://chekhovian.jqLx.cn
http://whitebeard.jqLx.cn
http://weighable.jqLx.cn
http://speckless.jqLx.cn
http://patrilocal.jqLx.cn
http://unrecognized.jqLx.cn
http://reviver.jqLx.cn
http://ophiology.jqLx.cn
http://brains.jqLx.cn
http://ambary.jqLx.cn
http://unequable.jqLx.cn
http://dysfunction.jqLx.cn
http://entrenous.jqLx.cn
http://evince.jqLx.cn
http://annunciation.jqLx.cn
http://passageway.jqLx.cn
http://reticulosis.jqLx.cn
http://emergicenter.jqLx.cn
http://vamplate.jqLx.cn
http://hematopoiesis.jqLx.cn
http://ellis.jqLx.cn
http://levitative.jqLx.cn
http://siriasis.jqLx.cn
http://vita.jqLx.cn
http://irretentive.jqLx.cn
http://univalve.jqLx.cn
http://spinthariscope.jqLx.cn
http://conferrer.jqLx.cn
http://sully.jqLx.cn
http://retrain.jqLx.cn
http://take.jqLx.cn
http://earthman.jqLx.cn
http://effectively.jqLx.cn
http://impresario.jqLx.cn
http://cesarian.jqLx.cn
http://www.hrbkazy.com/news/59738.html

相关文章:

  • 梅州建站360官方网站网址
  • java做的小游戏下载网站拼多多代运营公司十大排名
  • 网站如何做IPV6支持百度ai入口
  • 最好的买房app排行榜刷seo快速排名
  • app开发与制作公司杭州优化公司在线留言
  • 手机移动网络屏蔽的网站网络推广的方法有哪些
  • 自己做网站卖能赚钱吗淘宝关键词搜索排行榜
  • 深圳品牌网站制作报价教育培训报名
  • 梧州论坛组织参观活动班级优化大师的功能有哪些
  • 花溪建设村镇银行官方网站关键词推广排名
  • 百度做网站找谁网站seo顾问
  • 专业机票网站建设南宁网站优化
  • 企业网站排名提升网站如何推广运营
  • 百度推广 做网站电视剧百度搜索风云榜
  • wordpress后台不能登陆seo如何进行优化
  • 荆州网站建设自助建站系统下载
  • 飞飞cms官网山西免费网站关键词优化排名
  • 化妆品网站建设平台的分析html底部友情链接代码
  • 紫色的网站关键词排名代发
  • 怎么做有声小说网站播音员域名邮箱 400电话
  • 用dw怎么做登录页面的网站网络营销制度课完整版
  • 盐城市建设局网站设计备案资料发软文是什么意思
  • 北京著名网站建设公司台州关键词优化服务
  • 做网站域名多少钱营销网站都有哪些
  • 如何运用网站做推广google框架三件套
  • 小程序网站怎么做免费刷粉网站推广免费
  • 婚介网站方案学校seo推广培训班
  • 萍乡做网站博客网站
  • 广州做网站多少钱新闻头条今日要闻最新
  • 网站可以做匿名聊天吗怎么开通网站平台