【Flutter API】Layer(rendering)

2021-12-02  本文已影响0人  popesa

在绘画期间,渲染树生成用来组合层的树,这些层被上传到引擎并由合成器显示。
此类是所有层的基类。
大多数层的属性可以变化,并且层可以移动到不同的父层。在发生这些变化之后,必须要重新组合这些层。层的树(layer tree )不会维护自己的脏数据。
层树组合成为scene。为了组合层树,创建一个SceneBuilder对象,并把创建的对象传递给层树根元素对象的addToScene方法。并调用SceneBuilder.build方法来获取Scene对象。然后Scene对象使用dart:ui.FlutterView.render来绘制出来。

Memory

层在帧之间会通过保留资源来加速渲染。一个层会保留资源,直到所有的LayerHandle对于这个层的引用都清空为止。
层对象在弃置之后不可再被使用。如果一个RenderObject对象需要在后面使用到Layer对象,那它必须要创建一个对于层对象引用的句柄(handle)。
RenderObject.layer属性会自动持有层对象的句柄,但是另外的层必须要有他们自己的LayerHandle
参考:RenderView.compositeFrame,其中实现了对于在显示时绘制RenderObject树的层的组合规则。

继承关系

此类的父类为AbstractNode(已翻译)

Mixed in types

DiagnosticableTreeMixin

此类的子类

ContainerLayerPerformanceOverlayLayerPictureLayerPlatformViewLayerTextureLayer

属性(省略了父类AbstractNode中的属性,以及debug属性)

alwaysNeedsAddToScenebool 子类可以将此重写为true以禁用保留呈现。

engineLayerEngineLayer? 保留创建此类对象的引擎层,以便于跨帧复用引擎的资源,从而获取更高的性能。
这个值可以传递给ui.SceneBuilder.addRetained,以告诉引擎这个层或它的任何后代都没有改变。例如,本机引擎可以重用在前一帧中呈现的纹理。例如,web引擎可以重用为前一个框架创建的HTML DOM节点。
这个值可以作为oldLayer参数传递给“push”方法,以告知引擎一个层正在更新先前渲染的层。例如,web引擎可以更新之前渲染的HTML DOM节点的属性,而不是创建新的节点。

nextSiblingLayer? 这个层是父层的子列表中的下一个兄弟层。

parentContainerLayer? 当前层在层树中的父层。
根节点此属性为null。
只有ContainerLayer的子类可以在层树中拥有子类。所有其他层类都用于层树中的叶子节点。

previousSiblingLayer? 当前层在层树中的前一个兄弟节点。

方法

addToScene(<wbr style="box-sizing: inherit;">SceneBuilder builder, [Offset layerOffset = Offset.zero]) → void 覆写此方法,以把当前层上传给引擎。返回用于保留渲染的引擎层。当没有相应的引擎层时,返回null。

adoptChild(<wbr style="box-sizing: inherit;">covariant AbstractNode child) → void 将参数节点标记为当前节点的子节点。子类在获得一个新的子类时应该调用这个函数。

dispose(<wbr style="box-sizing: inherit;">) → void

dropChild(<wbr style="box-sizing: inherit;">covariant AbstractNode child) → void

find<<wbr style="box-sizing: inherit;">S extends Object>(<wbr style="box-sizing: inherit;">Offset localPosition) → S? 搜索该层及其子树,在localPosition描述的点下查找第一个类型为S的注释。如果没有搜索到则返回null。
默认情况下,该方法只是以参数onlyFirst为true调用方法findAnnotations,并且返回第一个结果。因为在标注搜索时,仅方法findAnnotations会被递归的调用,在此方法中自定义的行为会被忽略,所以更倾向于覆写方法findAnnotations

关于层标注

注释是可以随层携带的任何类型的可选对象。只要所有者层包含该位置并被移动到该位置,就可以在某个位置找到注释。首先递归地访问每个子元素,然后访问这一层,从而在视觉上形成从前到后的顺序来搜索注释。注释必须满足给定的限制,比如类型和位置。
在这里找到值的常用方法是将AnnotatedRegionLayer推到层树中,或者通过覆盖findannotation添加所需的注释。
参考AnnotatedRegionLayer,在层树中放置值。

findAllAnnotations<S extends Object>(Offset localPosition) → AnnotationResult<S>

findAnnotations<S extends Object>(AnnotationResult<S> result, Offset localPosition, {required bool onlyFirst}) → bool 搜索该层和它的子树,寻找在由参数localPosition描述的位置并且类型为S的标注。
在方法 findfindAllAnnotations的默认实现中会调用此方法。重写此方法来定制层应该如何搜索注释,或者层是否有自己的注释要添加。

参数和返回值

参数result也是方法的输出,新找到的标注会被添加到末尾。
参数onlyFirst若为true,则表示在找到第一个结果后就会停止搜索;如果为false,那么搜索将会遍历整个子树。
返回值表示该层及其子树在此位置的不透明度。如果返回true,则该层的父层应该跳过该层后面的子层。换句话说,这一层对标注的类型是不透明的,并且会终止搜索,从而对在这一层后面的层进行搜索。如果返回为false,那么该层的父层可能会对其他兄弟层进行搜索。
返回值不影响父类是否添加自己的标注;换句话说,如果一个层要添加标注,那么它总是会添加标注,即使它的子层对这种类型的标注是不透明的。然而,父类返回的不透明性可能会受到其子类的影响,因此对这种类型的标注来说,它的所有祖先都是不透明的。

markNeedsAddToScene(<wbr style="box-sizing: inherit;">) → void 标注当前层已经发生了变化,并且应当调用方法addToScene
remove(<wbr style="box-sizing: inherit;">) → void 从父层的子列表中移除当前层。如果当前层的parent为null,不会有影响。
updateSubtreeNeedsAddToScene(<wbr style="box-sizing: inherit;">) → void 从当前层开始遍历层子树,并且决定是否需要addToScene
如果下面三个条件满足任何一个,则需要addToScene

ContainerLayer重写了此方法,从而在子节点上递归的调用此方法。

上一篇 下一篇

猜你喜欢

热点阅读