Flex元素布局规则总结,以及布局和容器
一、Flex中的元素分类
从功能层面可以把Flex中的元素分为组件(Components)和容器(Containers)两大类:
组件 - 是指那类具有明确交互或数据展示功能的元素,例如Button、Checkbox、Datagrid、List等。
容器 - 是指那类用来放置其他元素的元素,容器往往不具有特定的交互功能,主要的功能就是容纳元素。容器再细分又可以分为布局(Layout)容器和导航(Navigator)容器,其中布局容器的功能就是用来布局界面元素的,例如Application、Panel等;导航容器主要用于进行功能性的导航,进行界面切换,例如TabNavigator等。
二、FLex中的布局规则
FLex中的布局即指布局容器的布局方式,按布局特点可以分为两大类:基础布局和特殊布局。
基础布局 - 基于layout属性和constraint-based的布局,例如Application、Panel、Canvas等容器。
特殊布局 - 基于容器的功能,不同的容器具有非常特征明显的布局方式,例如Form、Grid、HDividedBox等。
基础布局
1. layout属性
通过容器的layout属性来设置布局方式,主要包括以下几种:
(1)vertical - 从上至下依次将子元素垂直放置在单一一列中,而水平对齐方式可以通过horizontalAlign来设置,垂直对齐方式可以通过verticalAlign来设置。
(2)horizontal - 从左至右依次将子元素水平放置在单一一行中,而水平对齐方式可以通过horizontalAlign来设置,垂直对齐方式可以通过verticalAlign来设置。
(3)absolute - 通过设置每个子元素的x/y属性来定位每个子元素,而容器不会自动调整子组件的位置。如果没有指定坐标,则所有的子元素都绘制在容器的左上角。
2. constraint-based
在容器的layout属性设置为absolute的情况下(Canvas除外,因为Canvas只有absoulte一种布局方式,因此Canvas默认如此),可以使用constraint-based布局。这种布局方式是通过子元素的4条侧边以及2条中心线与容器相应侧边和中心线的偏移量来决定子元素的定位的。相应的属性设置如下:
(1)left - 子元素左边离容器左侧的距离
(2)right - 子元素右边离容器右侧的距离
(3)top - 子元素顶边离容器顶部的距离
(4)bottom - 子元素底边离容器底部的距离
(5)horizontalCenter - 子元素水平中心线相对于容器水平中心线的偏移量,正数表示向容器底部方向的偏移,负数表示向容器顶部方向的偏移。
(6)verticalCenter - 子元素垂直中心线相对于容器垂直中心线的偏移量,正数表示向容器右侧的偏移,正数表示向容器左侧的偏移。
*说明:horizontalCenter、verticalCenter的优先级比其他四个属性的优先级更高,即当设置了horizontalCenter、verticalCenter,其他四个属性将被忽略。此外,Constraint-based布局必须在absolute的基础布局中才有效。由于Canvas容器的布局有且仅有absolute的,因此在Canvas中可以直接使用Constraint-based布局,而在其他容器中需要将layout属性设置为absolute后Constraint-based布局才有效,而且使用了Constraint-based布局后,设置x/y坐标将不再有意义。
特殊布局
1. Box
在absolute布局中,子元素的位置不会随着容器的大小的变化而重新调整,这在窗口大小发生变化可能会对界面的布局产生不可预料的影响,很多情况下希望子元素的位置能够随容器的大小变化而自动调整,Box布局就可以满足这个需求。
Box布局分为HBox和VBox,其中HBox布局与设置容器layout为horizontal是一致的,将子元素水平排列在一行中,而VBox则是将子元素垂直排在一列中。
2. DividedBox
分为HDividedBox和VDividedBox,DividedBox会将子元素划分为一个独立的分区,并且各个分区之间会存在一条调整栏,通过调整栏用于可以手动的调整各个分区的大小。
3. Tile
将其子元素排成一个或多个竖列或横行,在需要时增加新行或新列。将子元素水平放置时与HBox类似,不过不同的是tile并不将所有子元素放置在单独一行,而是在即将超过tile的宽度时进行换行。
所有的Tile容器单元格大小都相同。
Flex将Tile容器的单元格排在正方形网格中,每一个单元格内放入一个子元素。布局方式由direction属性决定。
4. Grid
与HTML中的Table很相似,可以定义行数、列数,并选择一个单元格来放置子元素。
5. Form
表单容器,用于构建表单,生成特定的表单布局
1、Halo组件也称MX组件,是Flex3的独有组件(按钮、文本字段、容器等)。而Flex4引入了新一代的组件,称为Spark。
Flex4同时支持Halo和Spark。但是很多Halo组件都有更新的Spark组件。
2、布局种类
Spark都支持下面的任何一种布局:
- BasicLayout:绝对布局。使用x,y坐标。
- HorizontalLayout:单行中横向排列。
- VerticalLayout:单列纵向排列。
- TileLayout:网格形式显示组件,创建尽可能多的行和列。
3、绝对布局
绝对布局,使用x,y坐标,允许控制元素的确切位置和大小。
容器的左上角代表坐标原点(0,0)。(Flex中,x坐标从左边开始;y坐标,从顶部开始。)
Application容器默认使用绝对布局。
x,y坐标为负值时,组件会移到视觉范围外。
4、基于约束的布局
在难以确定组件的精确坐标时,可以用绝对布局模式中基于约束的布局方式。基于约束的布局是相对于容器的4个边或容器的中心点来定位组件。
- 4个边: top,bottom,left,right
- 中心点: horizontalCenter,verticalCenter
- baseline:组件的上边与容器的距离
优点是,即使调整窗口大小也可以保持组件的相对位置不变。
5、增强的约束布局(Spark容器不支持,Spark组件支持)
可以在水平和垂直方向上任意创建隐藏的辅助线,然后基于辅助线定位组件。
约束行和约束列的设定(<mx:constraintColumns> <mx:constraintRows>):
- 固定约束: 由绝对数字(像素)来指定
- 相对约束: 根据容器大小的百分比来确定
- 内容大小约束: 约束行和约束列将和最大项目的大小相同
Halo的Canvas容器支持增强约束,Spark容器不支持增强约束,但是Spark组件可以放到Halo容器中。
6、自动布局
自动布局模式下,是将容器定向到位置元素中。
1)使用布局类
Spark容器有4种布局类,其中BasicLayout是绝对布局,其它下面三种则提供了自动布局选项:
- HorizontalLayout
- VerticalLayout
- TileLayout (自动网格布局)
2)使用空间
<mx:Spacer/>组件可以在布局类指定的方向上,使组件隔开相对的距离。
例: <mx:Spacer width=”50%”> // 使组件平均地分开相对距离
7、容器
1)Application
一个应用程序只能有一个,是根容器。
有个特色属性preloader,是启动Flex程序时的进度条。默认是On的,可以Off。
可以装载全局变量和函数。
2)Canvas
是一种最基本的容器,是Halo组件。在增强约束时使用。
3)Group
是一个简单容器,和布局类结合使用,默认BasicLayout布局。
子容器有Hgroup和Vgroup。
4)SkinnableContainer
类似Group,支持换肤。
5)Panel
基于SkinnableContainer,特点在于添加了一个标题栏和一个框架,并默认给子对象绘制边框。
默认使用BasicLayout。
6)ApplicationControlBar
给程序添加了控制栏,和File菜单类似。要和Application容器结合使用。
(ControlBar和它类似,但是效果不好,避免)
7)DataGroup
用于分组数据,可以使用项渲染器渲染数据,从而自定义显示。默认是BasicLayout。
需要将数据发送给DataGroup的dataProvider。
为了显示数据,可以使用如下渲染器:
- spark.skins.spark.DefaultItemRenderer:显示为简单文本
- spark.skins.spark.DefaultComplexItemRenderer:显示为Group容器内的组件。只有当数据包含视觉组件时才有效。
8) SkinnableDataContainer
类似DataGroup,支持换肤.
9)DividedBox、HDividedBox、VDividedBox
这些是Halo组件,他们允许控制大小的调整。
DividedBox支持通过direction属性设置水平和垂直布局方式。
HDividedBox是水平布局,VDividedBox是垂直布局。
10)Form
方便布局表单,纯粹是布局目的。
它包含三个标签
- Form:主容器
- FormHeader:可选,添加标题用
- FormItem:将文本与每个表单输入字段关联
11)Grid
类似HTML的表,顶级的Grid标签用于标识网格的开始,GridRow用于插入行,GridItem用于向网格中输入数据。
下面是使用容器的简单代码(所用到的Skin代码就省略了,FB默认做成的就行):