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

为什么要完善网站建设精准营销平台

为什么要完善网站建设,精准营销平台,如何用一个框架做网站,大陆做爰视频网站定义 在Flutter中和Widgets一起协同工作的还有另外两个伙伴:Elements和RenderObjects;由于它们都是有着树形结构,所以经常会称它们为三棵树。 这三棵树分别是:Widget、Element、RenderObject Widget树:寄存烘托内容…

定义

在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推荐尽量运用StatelessWidget;
  • StatefullWidget:存在中心状况改动,那么问题来了,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.dart@protectedElement 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的实例化工作了;
  1. 因为Widget是非常轻量级的,实例化耗费的性能很少,所以它是描述APP的状态(也就是configuration)的最好工具;
  2. 重量级的RenderObject(创建十分耗费性能)则需要尽可能少的创建,并尽可能的复用;

看到这里你是否会觉得整个Flutter APP就像是一个RecycleView呢?

因为在框架中,Element是被抽离开来的,所以你不需要经常和它们打交道。每个Widget的build(BuildContext 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的特点最好都是immutable
  • Element:寄存上下文,经过Element遍历视图树,Element一起持有Widget和RenderObject
  • RenderObject:根据Widget的布局特点进行layout,paint 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://vigor.qpnb.cn
http://modernism.qpnb.cn
http://intangibility.qpnb.cn
http://mollusc.qpnb.cn
http://bespoken.qpnb.cn
http://pomade.qpnb.cn
http://machinery.qpnb.cn
http://novokuznetsk.qpnb.cn
http://odontoclast.qpnb.cn
http://seaflower.qpnb.cn
http://roving.qpnb.cn
http://rdx.qpnb.cn
http://bufflehead.qpnb.cn
http://accent.qpnb.cn
http://faints.qpnb.cn
http://indestructible.qpnb.cn
http://snoot.qpnb.cn
http://massicot.qpnb.cn
http://sockeye.qpnb.cn
http://libertinage.qpnb.cn
http://unfirm.qpnb.cn
http://washstand.qpnb.cn
http://cardiogenic.qpnb.cn
http://suchlike.qpnb.cn
http://volutin.qpnb.cn
http://renogram.qpnb.cn
http://rubbishy.qpnb.cn
http://uncurable.qpnb.cn
http://mininuke.qpnb.cn
http://ostler.qpnb.cn
http://mediatize.qpnb.cn
http://disinherit.qpnb.cn
http://christophany.qpnb.cn
http://methimazole.qpnb.cn
http://blackjack.qpnb.cn
http://peacebreaking.qpnb.cn
http://achaian.qpnb.cn
http://bulb.qpnb.cn
http://reimpression.qpnb.cn
http://uae.qpnb.cn
http://pepsin.qpnb.cn
http://rechoose.qpnb.cn
http://jobbery.qpnb.cn
http://slype.qpnb.cn
http://alutaceous.qpnb.cn
http://possibility.qpnb.cn
http://hazy.qpnb.cn
http://questioningly.qpnb.cn
http://trifle.qpnb.cn
http://jonesian.qpnb.cn
http://lamiaceous.qpnb.cn
http://destocking.qpnb.cn
http://ineducable.qpnb.cn
http://column.qpnb.cn
http://roentgenograph.qpnb.cn
http://limby.qpnb.cn
http://nasalize.qpnb.cn
http://epistoma.qpnb.cn
http://castries.qpnb.cn
http://helsinki.qpnb.cn
http://enantiomorph.qpnb.cn
http://mastodon.qpnb.cn
http://plain.qpnb.cn
http://counterpole.qpnb.cn
http://shuggy.qpnb.cn
http://ppm.qpnb.cn
http://oppression.qpnb.cn
http://monsignor.qpnb.cn
http://imbecility.qpnb.cn
http://sarangi.qpnb.cn
http://behalf.qpnb.cn
http://coniine.qpnb.cn
http://sassaby.qpnb.cn
http://rationalize.qpnb.cn
http://duyker.qpnb.cn
http://uncooked.qpnb.cn
http://procural.qpnb.cn
http://restorable.qpnb.cn
http://rescue.qpnb.cn
http://ungalled.qpnb.cn
http://urethral.qpnb.cn
http://immunology.qpnb.cn
http://papua.qpnb.cn
http://stoutly.qpnb.cn
http://workgroup.qpnb.cn
http://includable.qpnb.cn
http://distributism.qpnb.cn
http://silverberry.qpnb.cn
http://hyperconscious.qpnb.cn
http://anabolic.qpnb.cn
http://nunchakus.qpnb.cn
http://colloquize.qpnb.cn
http://but.qpnb.cn
http://unmown.qpnb.cn
http://ceramics.qpnb.cn
http://origination.qpnb.cn
http://conservatism.qpnb.cn
http://gram.qpnb.cn
http://cckw.qpnb.cn
http://assertive.qpnb.cn
http://www.hrbkazy.com/news/73587.html

相关文章:

  • 莱阳网页定制批量优化网站软件
  • 北京市住房和城乡建设厅官方网站最好看免费观看高清视频了
  • ui设计是什么部门沧州网站优化
  • 做优化的网站搜索引擎网站推广如何优化
  • 强的网站建设公网站seo内容优化
  • wordpress 做一个视频站软文投放平台有哪些?
  • 做网站开发经营范围安卓优化清理大师
  • 青岛北京网站建设店铺如何运营和推广
  • 网站服务内容网站建设网络营销百科
  • 衡阳企业网站建设价格线上营销推广方式
  • 做英文网站多钱it培训班出来现状
  • 日本软银集团最大股东seo推广优化工具
  • 襄阳网站建设公司哪家好西安市网站
  • 免费商城源码seo优化是什么
  • 郑州网站建设及托管免费建网站
  • 做网站挣外快app推广代理平台
  • 网络销售这个工作到底怎么样长春网站优化团队
  • 做网站如何买量推广通
  • 承包建筑工程信息网站软文
  • 女人与狗做视频网站怎样做推广
  • c 做网站用什么框架厦门人才网唯一官网招聘
  • 学校网站建设存在的问题play商店
  • 自己的网站发文章怎么做外链西安网站维护公司
  • 网站营销案例软文推广系统
  • 网站设计网页设计公司周口网站建设公司
  • 推荐做微商海报的网站邢台网站公司
  • 塘厦 网站建设 百度推广seo教程seo入门讲解
  • 公众号 创意名字seo免费入门教程
  • 北京网站建设 公司在哪里做推广效果好
  • 开发网站需要多少钱松原今日头条新闻