箱子布局攻略 (HBox/VBox Layout)

简介: 一、了解箱子布局箱子布局是一种新颖的布局方式,其布局模型可以更好地优化UI设计的工作。它率先在 XUL 界面语言中被提出,广泛应用于 Mozilla 的应用程序,如 FireFox 等等。在 CSS 布局系统中(for CSS v3),作为新增的补充形式,箱子布局可以指定子元素在水平或垂直的任意一种方向进行排列,剩下有多的空间由已声明了的子元素来填空(声明 flex 项)。

一、了解箱子布局

箱子布局是一种新颖的布局方式,其布局模型可以更好地优化UI设计的工作。它率先在 XUL 界面语言中被提出,广泛应用于 Mozilla 的应用程序,如 FireFox 等等。在 CSS 布局系统中(for CSS v3),作为新增的补充形式,箱子布局可以指定子元素在水平或垂直的任意一种方向进行排列,剩下有多的空间由已声明了的子元素来填空(声明 flex 项)。

我们知道,在 Ext JS 中,容器里面是用来放置组件的,至于容器内的子组件怎么排列就由布局风格来指定。3.0 提供了新的基于箱子模型的布局方式,分别是 Hbox 和 Vbox,对应的命名空间是 Ext.layout.HBoxLayout 和 Ext.layout.VBoxLayout。HBox 全称 Horizontal Box,其中所有子项都是自动按顺序横排。VBox 则相反,全称 Vertical Box,里面为竖排方式。所谓箱子模型的意思,就是将显示部分分割成一系列的 box,按照水平的或垂直的两种方位排列组织。水平 box 可以将其子组件排成一条线,而垂直 box  可以将其子组件定位成垂直方向。如果既然要水平方向和垂直方向两个方向填充内容,我们可以相互内嵌布局,即水平布局内嵌垂直布局,或垂直布局内嵌水平布局。

透过下图的一个例子可以看到两种方向的不同。


箱子模型的理论其实很人性化,既可以支持固定值尺寸的子项内容,也可以支持自适应的子项。箱子布局中的元素可以分配一个固定的值,也有可能加大尺码,这是容器空间有余的情况;另一种情况,则是容器空间不够容纳元素,就缩小某个元素的尺寸以适应。作用在那个元素身上?有 flex 配置项的子项元素,也就是说,HBox/VBox 布局会把有设定 flex 配置的子项划分垂直或水平的空间。另外,容器中元素的位置和顺序也会某程度地改变。

二、API攻略

a.flex 配置项

flex 配置项不是设置在布局上,而是设置在子项的配置项。每个子项相对的 flex 值都会与全体子项 flex 累加的值相比较,根据此结果,处理每个子项的 flex 最后是多少。若不设置子项的 flex,表示不对子项作自适应尺寸的处理,相当于 flex = 0 的子项或 flex = undefined 的时候,表示子项不会自伸缩处理,而采用最初的尺寸。

如下例:

{ layoutConfig: { padding:'5', align:'top' }, defaults:{margins:'0 5 0 0'}, items:[{ xtype:'button', text: 'Button 1', flex:1 },{ xtype:'button', text: 'Button 2', flex:1 },{ xtype:'button', text: 'Button 3', flex:1 },{ xtype:'button', text: 'Button 4', flex:3, margins:'0' }] }

该配置项效果如下图:

如果子项都设置相同 flex 值,那就意味着全体子项作相同的处理。

技巧:我们可以只让一个 panel 设定 flex,便可以作为填充空白的 spacer:

{ layoutConfig: { padding:'5', align:'top' }, defaults:{margins:'0 5 0 0'}, items:[{ xtype:'button', text: 'Button 1' },{ xtype:'spacer', flex:1 },{ xtype:'button', text: 'Button 2' },{ xtype:'button', text: 'Button 3' },{ xtype:'button', text: 'Button 4', margins:'0' }] } 效果如下:

flex 的文档也不是说得太清楚,不过我们可以多参考官方例子是怎么使用 flex 的。一旦你明白了flex 这个概念之后,它会非常灵活地进行布局。

b.如何对齐 align & pack

当然我们可以 Vbox 布局中内嵌 hbox 布局,或者 hbox 中内嵌 vbox,HBox 和 VBox 之间是可以允许嵌套布局的,但实际不必如此手动去做, Ext JS 为我们提供了“对齐 align/pack”的这一对方向各异的调整配置,代替了上述“内嵌”的这一种稍微让人感觉别扭。容器中每一个子项都遵循用户指定的 align/pack 对齐方式。一般设置的地方是在容器的 layoutConfig 配置项对象中,如下面某一个容器的代码片断:

layout:'hbox', layoutConfig: { align : 'stretch', pack : 'start', }, items: [ {html:'panel 1', flex:1}, {html:'panel 2', width:150}, {html:'panel 3', flex:2} ]

对于垂直布局的 VBox 而言,属性 align 就是水平对齐的设置了,align 有以下可选项:

键值 作用
left 居左,从容器的 left 开始水平对齐。这是系统默认的选项。
center 居中,从容器的 mid-width 开始垂直对齐。
stretcn 拉伸子项以填充容器的水平宽度。
stretcnmax 拿最宽的那个子项拉伸,适应容器的水平宽度。

属性 pack 是控制容器里面的子项是如何停靠的,这是垂直方向本身的对齐。有如以下设置:

键值 作用
start 居顶,从容器的 top 停靠子项。这是系统默认的选项。
center 居中,也就是子项都从容器的 mid-height 上开始停靠。
end 居底,从容器的底部边边开始往上摆子组件。

对于水平布局的 HBox 而言,align 就是决定如何垂直对齐,align 的可选项有如下:

键值 作用
top 顶部对齐,从容器的 top 开始垂直对齐。
middle 居中对齐,从容器的 middle 开始垂直对齐。
stretch 拉伸子项以填充容器的垂直高度。
stretchmax 拿最高的那个子项拉伸,适应容器的垂直高度。

pack的可选项有以下几种:

键值 作用
start 居左,从左边开始排列内容。
center 居中,也就是从容器的 mid-width 开始停靠内容。
end 居右,从容器的右边开始停靠内容。

对于 top、middle/center 我们能够一眼地看出是什么意思,而 stretch/stretchmax 又是什么用法呢?一图胜千言,我们看看下面这张图(点击图片运行例子以了解更多的适用情形):

v

c.设置内外边距

BoxLayout 可设置外边距(margins)。关于 defaultMargins,就是如果不制定每个子项的 margins 属性,那么就会使用默认的 margins。规定 defaultMargins 的格式如下:

{ top: (top margin), right: (right margin), bottom: (bottom margin), left: (left margin) }

默认为 {top:0, right:0, bottom:0, left:0} 。margin 属性接纳的格式也可以是字符串的,规定为空格隔开,数字类型的 margin 值。各个方向的排列顺序为 CSS 的顺序:

  • 如果只是一个值,就是各个方向都是这个值。
  • 如果有两个值,那么第一个值代表是上下方向的值,第二值则是左右方向的值。
  • 如果有三个值,第一个值是顶部的值,第二个值是左右两边的值,第三个值是底部的值。
  • 如果有四个值,分别代表就是顶部、右边、底部和左边的值(为方便记忆,可理解为顺时针方向)。

BoxLayout 可设置内边距(padding)。跟 defaultMargins 差不多,padding 属性接纳的格式也可以是字符串的,其格式规定为空格隔开,数字类型的 margin 值。各个方向的排列顺序为 CSS 的顺序。

三、小结

需要说明的是,H & V 箱子模型只限特定的应用场合使用,不是在任何布局都可适应。例如,H & V BoxLayout 就不支持渲染表单的 fieldLabels。要解决此问题,可以为 fieldLables 增加一层 layout:'form' 的容器。尽管理论上可设计一个满足多样需求的布局,但性能会是一大障碍(可参阅 http: //www.extjs.com/forum/showthread.php?p=396565#post396565)。也可以使用其他的布局风格,如 TableLayout 代替,但 TableLayout 一个明显的不足是其子项的增、删、改都不太方便;再如浮动布局 FloatLayout,FloatLayout 很像水平布局的 HBoxLayout,支持 x/y 的绝对布局,不过就没有自适应大小的功能。如果没有大小尺寸不够放得下,就换行显示。FloatLayout 同样有拉伸子项的功能,也支持 top/bottom/middle 对齐,以及居中、居左、居右的功能。

可见,H & V BoxLayout 越来越备受推崇,必须把它弄懂才行。学习游泳最好的方法就是跳进水里大胆试试,把上面的例子和官方源码当作你的湖吧!

四、延伸阅读:

目录
相关文章
|
5月前
|
Android开发
Android Studio入门之常用布局的讲解以及实战(附源码 超详细必看)(包括线性布局、权重布局、相对布局、网格布局、滚动视图 )
Android Studio入门之常用布局的讲解以及实战(附源码 超详细必看)(包括线性布局、权重布局、相对布局、网格布局、滚动视图 )
166 0
|
Android开发 容器
android RelativeLayout 控件绕中心点布局
android RelativeLayout 控件绕中心点布局
119 0
android RelativeLayout 控件绕中心点布局
|
XML Android开发 数据格式
Android笔记:标题栏颜色渐变效果的实现
Android笔记:标题栏颜色渐变效果的实现
186 0
Android笔记:标题栏颜色渐变效果的实现
|
Android开发
Android之解决toolbar里面显示返回按钮图片太大和没有水平居中的问题
Android之解决toolbar里面显示返回按钮图片太大和没有水平居中的问题
272 0
|
编解码 API Android开发
Android开发之AbsoluteLayout绝对布局
Android开发之AbsoluteLayout绝对布局
162 0
Android开发之AbsoluteLayout绝对布局
|
缓存 Android开发 数据安全/隐私保护
Android 悬浮窗、悬浮球开发
原文:Android 悬浮窗、悬浮球开发 1、权限管理 直接看我另外一篇博客吧,传送门: https://my.
1782 0
|
Android开发 容器 数据格式
Android实践(一)| Fragment实现底部导航栏(解决重叠问题)
最初学习Android的时候,是边学习边做着一个小项目的,因为项目需求,需要实现一个底部导航栏的功能,由于基础知识受限,百度了很多博客,大致就找到两种实现方案:第一种就是直接用Fragment实现(点击切换),第二种是ViewPager+Fragment实现(除了点击切换,还支持左右滑动切换)。
2264 0
|
Android开发
Android使用CardView多出的角,怎么办?
某天一个同事问我,为什么他使用CardView会变成这样? 我看了他的代码 注意一行 app:cardbackgroundColor="@color/transparent" 原因就是透明色 去掉之后就正常...
1065 0