Flutter基础技术:什么是Widget、RenderObject和Element?
你可能已经知道如何使用StatelessWidget和StatefulWidget了。但这些小部件只是将其他小部件组合在一起。添加到屏幕的布局和绘图发生在其他地方。
**我强烈建议你打开你最喜欢的编辑工具,然后按照本文一步步看看实际代码是如何实现的,并一路“结果”。 ,
## 不透明度组件
最好从不透明度组件开始。这个小部件非常简单,也是一个很好的例子。
它只接受一个子组件。因此,您可以设置任何小部件的不透明度来更改其显示。还有一个值 Opacity
,该值介于 0.0 和 1.0 之间。它用于控制透明度。
Opacity
是SingleChild RenderObject Widget
的子类。传承路径是这样的:
Opacity -> SingleChildRenderObjectWidget -> RenderObjectWidget -> Widget。
和StatelessWidget
和StatefulWidget
是这样的:StatelessWidget
和StatefulWidget
是这样的:d一起,d'组件不透明度控制组件的绘制方式。
但是如果你想找到一些从不透明度代码中绘制像素的提示,那几乎是徒劳的。这是因为小部件仅包含配置信息。例如,组件 opacity
仅包含不透明度值。
这就是为什么您可以在组件的 build
方法中创建新的小部件。它不包含任何构建组件的消耗资源的代码,而仅包含构建的一些信息。
绘画
绘画时会发生什么?
RenderObject
图纸都是在RenderObject
完成的。 光看名字就知道了。 Opacity 组件像这样创建和更新 RenderObject:
@override
RenderOpacity createRenderObject(BuildContext context) => new RenderOpacity(opacity: opacity);
@override
void updateRenderObject(BuildContext context, RenderOpacity renderObject) {
renderObject.opacity = opacity;
}
RenderOpacity
Opacity
组件将其自身的大小和子组件的大小设置为相同的值。除了绘图之外,它与其子组件的所有其他方面基本上相同。在绘制子组件之前添加不透明度值。
在这种情况下,RenderOpacity
必须实现所有方法(例如执行布局、碰撞检测和计算大小),然后交给子类来做具体的工作。
RenderOpacity
继承RenderProxyBox
(此类混合在其他一些类中)。这些类分别实现了上述方法。
double get opacity => _opacity;
double _opacity;
set opacity(double value) {
_opacity = value;
markNeedsPaint();
}
我(作者)删除了大部分代码。如果您想查看完整的代码,可以在这里查看。
getter 暴露了私有值。 setter 调用 markNeedsPaint()
或 markNeedsLayout()
。顾名思义,它会通知系统“这个组件发生了变化,需要重新绘制或者重新布局”
在RenderOpacity
:
@override
void paint(PaintingContext context, Offset offset) {
context.pushOpacity(offset, _alpha, super.paint);
}
这一行就是opacity的具体实现。 Review 记住,小部件只是一种配置, 在 Flutter 中,您基本上总是创建新的小部件。当调用方法 您无法获取屏幕上组件的大小或位置,因为组件表现为蓝图,并且实际上并未绘制在界面上。它仅包含渲染对象所需的信息。 Element 是组件树的实际组件。 第一次创建组件时,创建了一个元素,并将两者链接在一起。然后该元素被插入到树中。如果组件(小部件)发生变化,请将其与旧组件进行比较并相应地更新元素。最重要的是,此时的元素并没有再次创建,而只是更新。 Element 是 Flutter 核心的一部分,但你现在不需要知道。这些就足够了。 请参阅如果你好奇的话。在 如果Element创造了RenderObject,那么RenderObject自己是如何创造不透明组件的呢? 基本上是因为不透明度组件只需要 参见以下代码: 在 当元素被挂载时,组件只允许创建渲染对象。 这就是不透明度组件的工作原理。 我的目标是通过这篇文章来介绍组件背后的原理。还有很多我没有涉及到,但我希望这篇文章至少能让您一睹其风采。Context中也有这样的代码是一块画布。这个画布上有一个方法叫做
pushOpacity
! opacity不是
upStatelessWidget
或Statefullwidget,但alechildRendeObjectWidgetWidget。
Opacity
包含值 Opacity。 RenderOpacity
,继承自RenderProxyBox
,执行特定的布局和绘制动作就这些了吗?
RenderObject
是管理布局和绘图的。 build()
时,您将创建许多组件。 build方法基本上是在发生各种变化时调用的。例如,在动画中经常调用构建方法。 最好不要每次都绘制整个子树,更新会更好。 Element
发生了什么
不透明组件的元素在哪里创建的
SingleChildRenderObectWidget
中,@override
SingleChildRenderObjectElement createElement() => new SingleChildRenderObjectElement(this);
SingleChild RenderObject Element
也只是一个具有一个子元素的元素。 Element创造了RenderObject
RenderObject
,但不需要自定义元素。 SingleChildRenderObjectElement(SingleChildRenderObjectWidget widget) : super(widget);
SingleChildRenderObject元素
参考了RenderObjectWidget并且也包含在此处)。
RenderObjectElement#mount
方法中,将元素插入到元素树中: @override
void mount(Element parent, dynamic newSlot) {
super.mount(parent, newSlot);
_renderObject = widget.createRenderObject(this);
attachRenderObject(newSlot);
_dirty = false;
}
最后
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。