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

蚌埠市住房建设部网站网站开发实用技术第2版文档

蚌埠市住房建设部网站,网站开发实用技术第2版文档,东莞企业网站排名,潍坊外贸网站建设定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴#xff1a;Elements和RenderObjects#xff1b;由于它们都是有着树形结构#xff0c;所以经常会称它们为三棵树。 这三棵树分别是#xff1a;Widget、Element、RenderObject Widget树#xff1a;寄存烘托内容…定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴Elements和RenderObjects由于它们都是有着树形结构所以经常会称它们为三棵树。 这三棵树分别是Widget、Element、RenderObject Widget树寄存烘托内容、视图布局信息Element树根据 Widget 的布局特点进行 layout 和制作RenderObject树寄存上下文经过 Element 遍历视图树Element 一起持有 Widget 和RenderObject 三棵树原理 Widget 树 Widget 是用户页面的描述表明晰 Element 的配置信息Flutter 页面都是由各式各样的 Widget 组合声明成的。Widget本身是不可变的 immutable 这也便是说一切它直接声明或承继的变量都必须为 final 类型的。如果想给 widget 相关一个可变的状况就要考虑运用 StatefulWidget 它会经过 createState 创立一个State目标然后每当它转化成一个 Element 时会合并到树上。 而对于 Widget 又分为无状况的 StatelessWidget 和有状况的 StatefullWidget StatelessWidget无中心状况改动的widget需求更新展现内容就得经过从头创立flutter推荐尽量运用StatelessWidgetStatefullWidget存在中心状况改动那么问题来了widget不是都immutable的状况改动存储在哪里flutter 引进state的类用于寄存中心态经过调用state.setState()进行此节点及以下的整个子树更新 State 一个StatefulWidget类会对应一个State类State表明与其对应的StatefulWidget要保护的状况State中的保存的状况信息可以 在 Widget 构建时可以被同步读取。 在 Widget 生命周期中可以被改动当State被改动时可以手动调用其setState()办法通知Flutter framework状况发生改动Flutter framework 在收到音讯后会从头调用其build办法从头构建Widget树然后到达更新UI的意图。 对于Widget的生命周期这篇文章有介绍juejin.cn/post/703469… Element 树 Widget 树是十分不稳定的经常会履行 build 办法一旦调用 build 办法意味着这个 Widget 依靠的一切其他 Widget 都会从头创立如果 Flutter 直接解析 Widget树将其转化为 RenderObject 树来直接进行烘托那么将会是一个十分消耗功能的进程那对应的肯定有一个东西来消化这些改动中的不方便来做cache。 所以这儿就有另外一棵树 Element 树。Element 树这一层将 Widget 树的改动做了抽象可以只将真正需求修正的部分同步到实在的 RenderObject 树中最大程度下降对实在烘托视图的修正提高烘托效率而不是毁掉整个烘托视图树重建。 RenderObject 树 烘托树的使命便是做组件的详细的布局烘托作业烘托树上每个节点都是一个承继自 RenderObject 类的目标在 Element 中有 createRenderObject 生成RenderObject该目标内部提供多个特点及办法来协助框架层中的组件如何布局烘托。RenderObject 用于使用界面的布局和制作保存了元素的巨细布局等信息实例化一个 RenderObject 是十分耗费功能的。 初次运行三棵树 初步认识了三棵树之后那Flutter是如何创建布局的以及三棵树之间他们是如何协同的呢接下来就让我们通过一个简单的例子来剖析下它们内在的协同关系 class ThreeTree extends StatelessWidget {overrideWidget build(BuildContext context) {return Container(color: Colors.red,child: Container(color: Colors.blue));} }上面这个例子很简单它由三个Widget组成ThreeTree、Container、Text。那么当Flutter的runApp()方法被调用时会发生什么呢 当runApp()被调用时第一时间会在后台发生以下事件 Flutter会构建包含这三个Widget的Widgets树Flutter遍历Widget树然后根据其中的Widget调用createElement()来创建相应的Element对象最后将这些对象组建成Element树接下来会创建第三个树这个树中包含了与Widget对应的Element通过createRenderObject()创建的RenderObject 下图是Flutter经过这三个步骤后的状态 从图中可以看出Flutter创建了三个不同的树一个对应着Widget一个对应着Element一个对应着RenderObject。每一个Element中都有着相对应的Widget和RenderObject的引用。可以说Element是存在于可变Widget树和不可变RenderObject树之间的桥梁。Element擅长比较两个Object在Flutter里面就是Widget和RenderObject。它的作用是配置好Widget在树中的位置并且保持对于相对应的RenderObject和Widget的引用。 三棵树的作用 简而言之是为了性能为了复用Element从而减少频繁创建和销毁RenderObject。因为实例化一个RenderObject的成本是很高的频繁的实例化和销毁RenderObject对性能的影响比较大所以当Widget树改变的时候Flutter使用Element树来比较新的Widget树和原来的Widget树 //framework.dartprotectedElement updateChild(Element child, Widget newWidget, dynamic newSlot) {if (newWidget null) {if (child ! null)deactivateChild(child);return null;}Element newChild;if (child ! null) {assert(() {final int oldElementClass Element._debugConcreteSubtype(child);final int newWidgetClass Widget._debugConcreteSubtype(newWidget);hasSameSuperclass oldElementClass newWidgetClass;return true;}());if (hasSameSuperclass child.widget newWidget) {if (child.slot ! newSlot)updateSlotForChild(child, newSlot);newChild child;} else if (hasSameSuperclass Widget.canUpdate(child.widget, newWidget)) {if (child.slot ! newSlot)updateSlotForChild(child, newSlot);child.update(newWidget);assert(child.widget newWidget);assert(() {child.owner._debugElementWasRebuilt(child);return true;}());newChild child;} else {deactivateChild(child);assert(child._parent null);newChild inflateWidget(newWidget, newSlot);}} else {newChild inflateWidget(newWidget, newSlot);} ​assert(() {if (child ! null)_debugRemoveGlobalKeyReservation(child);final Key key newWidget?.key;if (key is GlobalKey) {key._debugReserveFor(this, newChild);}return true;}());return newChild;} ...static bool canUpdate(Widget oldWidget, Widget newWidget) {return oldWidget.runtimeType newWidget.runtimeType oldWidget.key newWidget.key;}如果某一个位置的Widget和新Widget不一致才需要重新创建Element如果某一个位置的Widget和新Widget一致时(两个widget相等或runtimeType与key相等)则只需要修改RenderObject的配置不用进行耗费性能的RenderObject的实例化工作了 因为Widget是非常轻量级的实例化耗费的性能很少所以它是描述APP的状态也就是configuration的最好工具重量级的RenderObject创建十分耗费性能则需要尽可能少的创建并尽可能的复用 看到这里你是否会觉得整个Flutter APP就像是一个RecycleView呢 因为在框架中Element是被抽离开来的所以你不需要经常和它们打交道。每个Widget的buildBuildContext context方法中传递的context就是实现了BuildContext接口的Element。 更新时的三棵树 因为Widget是不可变的当某个Widget的配置改变的时候整个Widget树都需要被重建。例如当我们改变一个Container的颜色为橙色的时候框架就会触发一个重建整个Widget树的动作。因为有了Element的存在Flutter会比较新的Widget树中的第一个Widget和之前的Widget。接下来比较Widget树中第二个Widget和之前Widget以此类推直到Widget树比较完成。 class ThreeTree extends StatelessWidget {overrideWidget build(BuildContext context) {return Container(color: Colors.orange,child: Container(color: Colors.blue,),);} }Flutter遵循一个最基本的原则判断新的Widget和老的Widget是否是同一个类型 如果不是同一个类型那就把Widget、Element、RenderObject分别从它们的树包括它们的子树上移除然后创建新的对象如果是一个类型那就仅仅修改RenderObject中的配置然后继续向下遍历 在我们的例子中ThreeTree Widget是和原来一样的类型它的配置也是和原来的ThreeTreeRender一样的所以什么都不会发生。下一个节点在Widget树中是Container Widget它的类型和原来是一样的但是它的颜色变化了所以RenderObject的配置也会发生对应的变化然后它会重新渲染其他的对象都保持不变。 注意这三个树配置发生改变之后Element和RenderObject实例没有发生变化。 上面这个过程是非常快的因为Widget的不变性和轻量级使得他能快速的创建这个过程中那些重量级的RenderObject则是保持不变的直到与其相对应类型的Widget从Widget树中被移除。 当Widget的类型发生改变时 class ThreeTree extends StatelessWidget {overrideWidget build(BuildContext context) {return Container(color: Colors.orange,child: FlatButton(onPressed: () {},child: Text(三棵树),),);} }和刚才流程一样Flutter会从新Widget树的顶端向下遍历与原有树中的Widget类型进行对比。 因为FlatButton的类型与Element树中相对应位置的Element的类型不同Flutter将会从各自的树上删除这个Element和相对应的ContainerRender然后Flutter将会重建与FlatButton相对应的Element和RenderObject。 全文到这大致为他的原理及代码解析有关更多的flutter的高级进阶知识大家可以参考《Flutter混合开发手册》这个技术文档里面包含flutter的全部技术覆盖。 Flutter三棵树联系 首先要知道启动App整个创立树的流程是什么 创立 widget 树调用 runApp(rootWidget)将 rootWidget 传给 rootElement 做为 rootElement 的子节点生成 Element 树再由 Element 树生成 Render 树 Widget:寄存烘托内容、视图布局信息,widget的特点最好都是immutableElement:寄存上下文经过Element遍历视图树Element一起持有Widget和RenderObjectRenderObject:根据Widget的布局特点进行layoutpaint Widget传人的内容 从创立到烘托的大体流程是 根据 Widget生成 Element然后创立相应的RenderObject并相关到Element.renderObject特点上最终再经过RenderObject来完结布局摆放和制作。Element便是Widget在UI树详细位置的一个实例化目标大多数Element只要仅有的renderObject但还有一些Element会有多个子节点如承继自RenderObjectElement的一些类比如MultiChildRenderObjectElement。最终一切Element的RenderObject构成一棵树咱们称之为Render Tree即烘托树。 总结一下咱们可以以为Flutter的UI系统包含三棵树Widget树、Element树、RenderObject树。他们的依靠联系是Element树根据Widget树生成而烘托树又依靠于Element树最终的UI树其实是由一个个独立的Element节点构成。
http://www.hkea.cn/news/14476670/

相关文章:

  • 个人网站做博客还是做论坛电子商务网店设计
  • 网站建设费用入什么科目陕西网站建设陕icp备
  • 济南网站制作服务那个网站可以做logo
  • 手机版网站有必要吗做游戏ppt下载网站
  • 婚庆公司网站建设方案天津黑曼巴网站建设
  • 长沙企业建网站费用网站建设图片设置
  • 建网站开源代码wordpress 爱主题
  • 个人网站备案网址导航app运营岗位职责
  • 宁夏交通建设股份有限公司网站北京微信网站设计报价
  • 黑别人网站官网首页设计
  • 住房建设建设部网站网站上社保做增员怎么做
  • 海淀做网站设计的公司wordpress 新建主题
  • 软件下载网站排行榜长沙网站制
  • 广州做网站星珀为什么要建设个人网站
  • 网站管理助手 伪静态公众号开发哪家专业
  • 技术支持 深圳网站建设贝尔利广州百度关键词排名
  • 我想做一个网站怎么办深圳做自适应网站设计
  • html网站注册页面全国十大教育机构
  • wordpress 招聘网站模板上海公共场所
  • 房地产景区网站建设方案网页制作作业网站
  • 一个网站项目多少钱简单的页面
  • 怎么创办自己的网站邻水建设局网站
  • 网站开发硬件成本制作网站设计的总结
  • 哪个网站可以做兼职ppt北京的网站建设
  • 建设网站全部流程wordpress is电影主题
  • 六枝做网站网站内容维护费用
  • 中国做铁塔的公司网站qq群推广平台
  • 周口哪里做网站分阶段建设网站
  • 巩义做网站贵阳网站制作策划
  • 佛山建设网站小企业网站 优帮云