设为首页收藏本站
网站公告 | 这是第一条公告
     

 找回密码
 立即注册
缓存时间11 现在时间11 缓存数据 以后别遇到像我这样的人敏感多疑 总是吵着让你陪我经常瞎想 总让你很累吧 但又希望碰到这样的人 因为这样的人真的真的很爱你

以后别遇到像我这样的人敏感多疑 总是吵着让你陪我经常瞎想 总让你很累吧 但又希望碰到这样的人 因为这样的人真的真的很爱你 -- 敏感多疑

查看: 1467|回复: 1

Flutter渲染原理深入解析

[复制链接]

  离线 

TA的专栏

  • 打卡等级:热心大叔
  • 打卡总天数:240
  • 打卡月天数:0
  • 打卡总奖励:3591
  • 最近打卡:2025-04-06 05:37:13
等级头衔

等級:晓枫资讯-上等兵

在线时间
0 小时

积分成就
威望
0
贡献
423
主题
379
精华
0
金钱
4836
积分
882
注册时间
2023-1-5
最后登录
2025-4-6

发表于 2023-5-12 22:03:57 | 显示全部楼层 |阅读模式
Widget Element RenderObject之间的关系


1 Widget

在Flutter 中,万物皆是Widget,无论是可见的还是功能型的。一切都是Widget.
官方文档中说的Widget 使用配置和状态来描述View 界面应该长什么样子。
它不仅可以表示UI元素,也可以表示一些功能性的组件如:用于手势检测的 GestureDetector、用于APP主题数据传递的Theme、布局元素等等
两个重要的方法
一个是通过 createElement 来创建 Element 对象的,
一个是根据 key 来决定更新行为的 canUpdate 方法。
在这个方法中会对比runtimeType (也就是widget 的类型)和 key 是否相同
  1. @immutable
  2. abstract class Widget extends DiagnosticableTree {
  3.   /// Initializes [key] for subclasses.
  4.   const Widget({this.key});
  5.   final Key? key;
  6.   @protected
  7.   @factory
  8.   Element createElement();
  9.   /// A short, textual description of this widget.
  10.   @override
  11.   String toStringShort() {
  12.     final String type = objectRuntimeType(this, 'Widget');
  13.     return key == null ? type : '$type-$key';
  14.   }
  15.   @override
  16.   void debugFillProperties(DiagnosticPropertiesBuilder properties) {
  17.     super.debugFillProperties(properties);
  18.     properties.defaultDiagnosticsTreeStyle = DiagnosticsTreeStyle.dense;
  19.   }
  20.   @override
  21.   @nonVirtual
  22.   bool operator ==(Object other) => super == other;
  23.   @override
  24.   @nonVirtual
  25.   int get hashCode => super.hashCode;
  26.   static bool canUpdate(Widget oldWidget, Widget newWidget) {
  27.     return oldWidget.runtimeType == newWidget.runtimeType &&
  28.         oldWidget.key == newWidget.key;
  29.   }
  30.   // Return a numeric encoding of the specific `Widget` concrete subtype.
  31.   // This is used in `Element.updateChild` to determine if a hot reload modified the
  32.   // superclass of a mounted element's configuration. The encoding of each `Widget`
  33.   // must match the corresponding `Element` encoding in `Element._debugConcreteSubtype`.
  34.   static int _debugConcreteSubtype(Widget widget) {
  35.     return widget is StatefulWidget
  36.         ? 1
  37.         : widget is StatelessWidget
  38.             ? 2
  39.             : 0;
  40.   }
  41. }
复制代码
2 Element

Element 就是一个Widget 的实例,在树中详细的位置。
An instantiation of a Widget at a particular location in the tree

3 RenderObject

渲染树上的一个对象。负责具体布局和绘制这些事情。

4 结合图说一下其三者的关系

230410xipry6kcf4c4qerl.png

230411tb5xbtqtwt55z5b5.png

从创建到渲染的流程 :
根据Widget 生成Element,然后创建响应的RenderObject并且关联到Element.renderObject 属性。最后再通过RenderObject 来完成布局和绘制。
依赖关系:
Element 树根据Widget 树生成,而渲染树又依赖于widget 树。

5 一些小问题

widget 和 element 是一一对应的吗 ? 为什么 ?
答:是一一对应的。
因为 abstract class Widget ,本身是一个抽象类,这个抽象类中有一个抽象方法叫做createElement(),子类必须实现这个抽象方法,所以是一一对应的。
widget 和 renderObject 是一一对应的吗 ? 为什么 ?
答:不是的
因为只有这个widget 继承自RenderObjectWidget 的时候,才会有对应的renderObject
像类似 Padding , Row,SizedBox,Center 这种组件继承自RenderObjectWidget的组件会有一一对应的关系
  1. //class Padding extends SingleChildRenderObjectWidget
  2. // Padding();
  3. // class Flex extends MultiChildRenderObjectWidget
  4. // Row()
复制代码
BuildContext 是什么 ?
答:是Element,不管是StatefulWidget 还是StatelessWidget 都会重写父类的build 方法,
build 方法传入的一个参数叫做BuildContext, 我们拿StatelessWidget来说,其本身创建一个StatelessElement,而在这个Element内部重写StatelessElement父类的build方法,而在这个build方法内部会调用_widget.build 方法,并且把this传递进去。那么这个this 就是element 。
  1. /// An [Element] that uses a [StatelessWidget] as its configuration.
  2. class StatelessElement extends ComponentElement {
  3.   /// Creates an element that uses the given widget as its configuration.
  4.   StatelessElement(StatelessWidget super.widget);
  5.   @override
  6.   Widget build() => (widget as StatelessWidget).build(this);
  7.   @override
  8.   void update(StatelessWidget newWidget) {
  9.     super.update(newWidget);
  10.     assert(widget == newWidget);
  11.     _dirty = true;
  12.     rebuild();
  13.   }
  14. }
复制代码
Widget 频繁更改创建是否会影响性能?复用和更新机制是什么样的?
不会影响性能,因为只是一些配置信息,没有有布局渲染到页面上去。中间层Element 会通过widget 的runtimeType 和 Key 来对比是否进行更新操作。
Build 方法会在什么时候调用 ?
Element 创建完毕之后会调用mount 方法,对于非渲染的ComponentElement 来说,mount主要执行的是Widget 中的build 方法。在StatelessElement 中直接使用的是 widget.build(this),
而在StatefullWidget 方法中,通过的是state.build(this)。在StatefulElement 这个类中,
初始化列表的给state 进行了赋值操作。通过widget调用createState方法之后,把state赋值给自己的_state 属性。
  1. StatefulElement(StatefulWidget widget)
  2. : _state = widget.createState(),
复制代码
createState 方法什么时候调用?
答:创建Element 的时候。
Flutter 会在遍历 Widget 树时调用 Widget 里面的 createElement 方法去生成对应节点的 Element 对象,同时执行 StatefulWidget 里面的 createState 方法创建 state,并且赋值给 Element 里的 _state 属性,当前 widget 也同时赋值给了 state 里的_widget,state 里面有个 widget 的get 方法可以获取到 _widget 对象。
到此这篇关于Flutter渲染原理深入解析的文章就介绍到这了,更多相关Flutter渲染原理内容请搜索晓枫资讯以前的文章或继续浏览下面的相关文章希望大家以后多多支持晓枫资讯!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
晓枫资讯-科技资讯社区-免责声明
免责声明:以上内容为本网站转自其它媒体,相关信息仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同其观点或证实其内容的真实性。
      1、注册用户在本社区发表、转载的任何作品仅代表其个人观点,不代表本社区认同其观点。
      2、管理员及版主有权在不事先通知或不经作者准许的情况下删除其在本社区所发表的文章。
      3、本社区的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,举报反馈:点击这里给我发消息进行删除处理。
      4、本社区一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
      5、以上声明内容的最终解释权归《晓枫资讯-科技资讯社区》所有。
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~

  离线 

TA的专栏

  • 打卡等级:小镇青年
  • 打卡总天数:83
  • 打卡月天数:0
  • 打卡总奖励:2040
  • 最近打卡:2024-07-09 12:11:20
等级头衔

等級:晓枫资讯-列兵

在线时间
4 小时

积分成就
威望
0
贡献
36
主题
14
精华
0
金钱
2115
积分
76
注册时间
2023-6-10
最后登录
2024-7-9

发表于 2023-10-26 20:08:01 | 显示全部楼层
感谢楼主分享~~~~~
http://bbs.yzwlo.com 晓枫资讯--游戏IT新闻资讯~~~
严禁发布广告,淫秽、色情、赌博、暴力、凶杀、恐怖、间谍及其他违反国家法律法规的内容。!晓枫资讯-社区
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1楼
2楼

手机版|晓枫资讯--科技资讯社区 本站已运行

CopyRight © 2022-2025 晓枫资讯--科技资讯社区 ( BBS.yzwlo.com ) . All Rights Reserved .

晓枫资讯--科技资讯社区

本站内容由用户自主分享和转载自互联网,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。

如有侵权、违反国家法律政策行为,请联系我们,我们会第一时间及时清除和处理! 举报反馈邮箱:点击这里给我发消息

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表