Skip to content

Latest commit

 

History

History
executable file
·
32 lines (23 loc) · 3.11 KB

File metadata and controls

executable file
·
32 lines (23 loc) · 3.11 KB

自动布局本质上就是封装了各种更加便捷的相对布局属性,结合失效验证机制,在合适的触发条件下(如尺寸发生改变时),自动设置相关对象的xywidthheight等属性。所以无论过程是怎么样的,最终结果都是直接体现在x,y,width,height这些最原始的属性上,并没有脱离显示对象原始的API。

在上一节内容中,简单介绍了跟布局有关的两个方法:measure()updateDisplayList()。本节详细说明这个两个方法:

updateDisplayList()方法负责布局子项(即设置子项的x,y,width,height),或做一些矢量重绘操作。measure()自动测量出当前适合子项的相关属性(width,height等)。

举个例子:有一个容器(Group),里面放一个单行文本(Label),想要文本始终在容器中水平居中(horizotalCenter = 0)。不需要显式设置文本的width,这时measure()会在文本内容改变时,自动测量出当前合适的width,父级就会根据这个width,重新布局它的x,y

EUI 里所有的组件都是这样:如果不显式设置宽高,就调用measure()方法测量出一个最佳尺寸,在没有被父级强制布局情况下,这个值最终赋值给widthheight属性。反之,如果显式设置了组件的widthheight属性,widthheight就使用显式设置的值。若组件同时被设置了widthheightmeasure()方法将不会被调用。至于何为测量的”最佳尺寸”?不同的组件有各自的测量方式,容器是能刚好放下所有子项的尺寸,文本是能完整显式文本内容的尺寸,而Image则是内部要显示的位图素材的尺寸。还有其他的组件,具体在各自的measure()方法里实现。多个组件都需要测量的时候,会按照显式列表深度,从内向外测量。而布局阶段正好相反,从外向内。具体细节参考失效验证机制的内容。

总之,如果希望自定义的组件像框架里的标准组件一样,能加入自动布局体系,就必须要同时重写measure()updateDisplayList()方法。

Group是容器基类。它不负责具体的布局规则,而是做了一个解耦处理。增加layout属性,类型为LayoutBaseGroup中的measure()updateDisplayList()方法的内容为:

protected measure():void {
    if (!this.$layout) {
        this.setMeasuredSize(0, 0);
        return;
    }
    this.$layout.measure();
}

protected updateDisplayList(unscaledWidth:number, unscaledHeight:number):void {
    if (this.$layout) {
        this.$layout.updateDisplayList(unscaledWidth, unscaledHeight);
    }
    this.updateScrollRect();
}

Group把自己的measure()方法交给layout.measure()实现,updateDisplayList()交给layout.updateDisplayList()实现。也就是把具体的布局方式解耦出来,形成独立的LayoutBase类。这样所有的容器都可以采用Group+LayoutBase的组合的方式,来设置任意的布局。