深入解析Flex布局:从基础到自定义
立即解锁
发布时间: 2025-08-18 00:51:38 阅读量: 1 订阅数: 6 

### 深入解析Flex布局:从基础到自定义
#### 1. 行列布局
在布局设计中,常常需要将子元素按行列顺序展示。可以通过为Spark容器的`layout`属性指定`TileLayout`,从而将子元素动态地放置在网格中。
```xml
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<fx:String id="txt">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</fx:String>
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:HSlider id="slider" minimum="100" maximum="400" value="250" />
<s:DataGroup width="{slider.value}"
itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:TileLayout />
</s:layout>
<s:dataProvider>
<s:ArrayCollection source="{txt.split(' ')}" />
</s:dataProvider>
</s:DataGroup>
</s:Application>
```
上述示例中,布局委托的父容器宽度会随`HSlider`控件的`value`属性变化而更新。宽度改变时,列会相应增减,目标`DataGroup`容器的子元素也会重新定位。
默认情况下,子元素按行添加到布局中。子元素沿水平轴在列中添加,直到到达容器边界,此时会创建新行继续添加。若有需要,可通过`TileLayout`的`orientation`属性更改添加顺序,其值可以是`rows`或`columns`。
```xml
<s:DataGroup width="{slider.value}"
itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:TileLayout orientation="rows" />
</s:layout>
<s:dataProvider>
<s:ArrayCollection source="{txt.split(' ')}" />
</s:dataProvider>
</s:DataGroup>
```
还能通过指定`TileLayout`的`requestedRowCount`和`requestedColumnCount`属性值,限制显示的行数和列数。默认值为 -1,表示行或列添加子元素数量无限制。
```xml
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<fx:Declarations>
<fx:String id="txt">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</fx:String>
</fx:Declarations>
<s:layout>
<s:VerticalLayout />
</s:layout>
<s:Group>
<s:Scroller>
<s:DataGroup width="100%"
itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:TileLayout requestedRowCount="2" requestedColumnCount="3"
clipAndEnableScrolling="true" />
</s:layout>
<s:dataProvider>
<s:ArrayCollection source="{txt.split(' ')}" />
</s:dataProvider>
</s:DataGroup>
</s:Scroller>
<s:Rect width="100%" height="100%">
<s:stroke>
<s:SolidColorStroke />
</s:stroke>
</s:Rect>
</s:Group>
</s:Application>
```
当指定非默认值时,若未直接为目标容器分配宽度和高度,容器尺寸由`TileLayout`按行列布局的子元素位置和大小决定。由于`TileLayout`严格按属性值定位子元素时会忽略容器尺寸,可能导致子元素超出计算的行列大小,因此示例中将目标`DataGroup`容器包裹在`Scroller`组件中,并将`clipAndEnableScrolling`属性设为`true`。
#### 2. 统一子元素大小
若希望容器内所有子元素大小相同,可使用`HorizontalLayout`和`VerticalLayout`的`columnHeight`和`rowHeight`属性限制子元素大小,也可通过`typicalLayoutElement`属性根据单个子元素尺寸动态调整和定位所有子元素。
默认情况下,`HorizontalLayout`和`VerticalLayout`的`variableRowHeight`和`variableColumnHeight`属性值为`true`,即子元素按各自测量尺寸显示。这在展示不同大小元素时有用,但运行时渲染成本可能较高。为加快渲染速度,可设置静态值确保子元素大小统一。
```xml
<s:Group>
<s:layout>
<s:VerticalLayout variableRowHeight="false" rowHeight="50" />
</s:layout>
<s:Button id="btn1" label="(1) button" />
<s:Button id="txt2" label="(2) button" height="10" />
<s:Button id="txt3" label="(3) button" height="30" />
<s:Button id="txt4" label="(4) button" />
</s:Group>
```
此例中,任何声明的`Button`控件的`height`属性值会被忽略,所有子元素垂直定位时高度相同。
```xml
<s:Group>
<s:layout>
<s:HorizontalLayout variableColumnWidth="false" columnWidth="80" />
</s:layout>
<s:Button id="btn1" label="(1) button" />
<s:Button id="btn2" label="(2) button" height="50" />
<s:Button id="btn3" label="(3) button" height="30" />
<s:Button id="btn4" label="(4) button" />
</s:Group>
```
在水平布局中,使用`columnWidth`和`variableColumnWidth`属性应用大小约束。
```xml
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark">
<s:Group>
<s:layout>
<s:VerticalLayout variableRowHeight="false"
typicalLayoutElement="{btn3}" />
</s:layout>
<s:Button id="btn1" label="(1) button" />
<s:Button id="btn2" label="(2) button" height="50" />
<s:Button id="btn3" label="(3) button" height="30" />
<s:Button id="btn4" label="(4) button" />
</s:Group>
</s:Application>
```
通过提供`ILayoutElement`实例作为`typicalLayoutElement`属性值,可根据该实例的宽度或高度调整和定位目标容器的子元素,之前分配的高度属性值会被忽略。
#### 3. 延迟创建和回收子元素
为提高运行时性能,可根据需要创建和渲染容器的子元素,使用目标容器为`DataGroup`的`HorizontalLayout`、`VerticalLayout`或`TileLayout`的`useVirtualLayout`属性。
虚拟化通过创建和回收项目渲染器,仅在子元素进入显示容器可见内容区域时进行渲染,从而提高运行时性能。继承`spark.layouts.LayoutBase`的布局类(如`VerticalLayout`)暴露了`useVirtualLayout`属性,其为布尔值,用于确定是否在支持虚拟化的数据元素容器(如`DataGroup`)中回收项目渲染器。使用虚拟化时,通过内容API方法(如`getElementAt()`)访问数据元素仅限于容器内容区域内可见的元素。
```xml
<fx:Declarations>
<fx:String id="txt">
Lorem ipsum dolor sit amet consectetur adipisicing elit.
</fx:String>
</fx:Declarations>
<s:Scroller>
<s:DataGroup width="150" height="120"
itemRenderer="spark.skins.spark.DefaultItemRenderer">
<s:layout>
<s:VerticalLayout useVirtualLayout="true" />
</s:layout>
<s:dataProvider>
<mx:ArrayCollection source="{txt.split(' ')}" />
</s:dataProvider>
</s:DataGroup>
</s:Scroller>
```
此例中,`DataGroup`容器大小受限,根据指定的项目渲染器和提供的数据,一次大约显示四个子元素。新子元素滚动到视图中时,之前滚动出视图的项目渲染器实例会被重用,以渲染新数据。
```xml
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="handleCreationComplete()">
<fx:Library>
<fx:Definition name="CustomRect">
<s:Rect width="100">
<s:fill>
<mx:SolidColor color="#000000" />
</s:fill>
</s:Rect>
</fx:Definition>
</fx:Library>
<fx:Script>
<![CDATA[
import spark.components.supportClasses.GroupBase;
private function handleCreationComplete():void
{
scroller.verticalScrollBar.addEventListener(Event.CHANGE,
inspectVirtualChildren);
}
private function inspectVirtualChildren( evt:Event ):void
{
var target:GroupBase = vLayout.target;
for( var i:int = 0; i < target.numElements; i++ )
{
trace( target.getElementAt( i ) );
}
}
]]>
</fx:Script>
<s:Scroller id="scroller">
<s:DataGroup width="150" height="120"
itemRenderer="spark.skins.spark.DefaultComplexItemRenderer"
```
0
0
复制全文
相关推荐










