UI界面布局容器与布局策略概述
博客专区 > 炽火 的博客 > 博客详情
UI界面布局容器与布局策略概述
炽火 发表于3个月前
UI界面布局容器与布局策略概述
  • 发表于 3个月前
  • 阅读 46
  • 收藏 0
  • 点赞 0
  • 评论 0
摘要: 本文描述了UI界面的容器与布局策略。主要从理论角度论述原理和实现思路,并包含一些容器的样例贴图。

>本文描述了UI界面的容器与布局策略。主要从理论角度论述原理和实现思路,并包含一些容器的样例贴图。

>本文写于2016年2月,现发布于博客和大家分享。原文是工作需要做的研究,博客基于原始草稿,并做了一定删减和增补。

UI界面的基本组成单位是UI元素,容器是用于容纳多个子元素的组件。布局实际上是一种算法策略,用于计算子元素在容器中的位置排列。

布局管理器用于管理容器布局策略,有两种实现方式:

  • 每种布局策略实现特定容器
  • 容器可以指定不同的布局策略(例如Swing)

一种常用的设计是每种布局对应一个容器,好处就是入门门槛低,容易上手,但容易造成仅仅为了布局的容器堆叠。而让容器可以指定不同布局策略是一种灵活的实现方式,但是使用起来比较繁琐。对于一个成熟产品来说,同时提供可以自由指定布局策略的容器,同时提供常用的布局容器,是一种比较好的方案。

对于复杂界面来说,容器嵌套层次太多容易造成冗余的布局调用,随着嵌套层次的增加而减低布局效率。扁平化容器层级能够提高界面布局效率。如何减少容器组合的嵌套层级?可以考虑将一些常用的嵌套方案,封装为一个固定的组合布局容器。

布局策略 Layout Policy

布局策略可以抽象为5种基本类型:

  • Coordinate Based 基于坐标
  • Constraint Based 基于约束
  • Linear 线性
  • Layered 分层
  • Grid 网格

基于坐标的布局策略 Coordinate–Based

这是最基本的布局策略,子元素可以用Bounds(Location和Size)来决定在容器中的显示边界(Boundary)。

基于约束的布局策略 Constraint-Based

这是一种相对定位的布局策略,对子元素设置约束条件,当容器变化时,子元素的边界遵循约束发生变化。

  • Relative Positioning 相对定位 设置元素的left, top, right, bottom相对父容器的位置。例如Java的SpringLayout。

  • Anchor Points 锚点 一个界面元素具有9个锚点:上、下、左、右、中心、左上、右上、右下、左下。当设置了元素的Bound边界后,元素可以定位在容器中。此时,可以指定一个或多个锚点,则当容器边界变化时,元素的锚点保持相对位置不变,单个锚点可以让元素跟随容器平移,多个锚点可以让元素跟随容器的改变而平移+缩放。

  • Dock 停靠 元素可以停靠在容器的指定位置上,共有上下左右中五个位置。Dock和Anchor是WinFrom的基本布局策略。Dock布局是Anchor的一种简化。在Java里也称为BorderLayout,采用东南西北中来描述五个方位。

  • Guide Lines 参考线。 例如BaseLine、Constraint Row, Constraint Column。同时设置元素的边界相对参考线的位置

线性布局策略 Linear

所有元素沿着一个方向延展。可以派生出横向、纵向、以及可以折行的流式布局等。

这种布局策略简单有效,是界面布局中最常用的布局策略。通过组合可以实现大多数常用的界面布局。

以下容器属于线性布局策略:

  • HBox
  • VBox
  • FlowLayout
  • SpitContainer

在不同的实现中有一些扩展属性,例如flex属性可以指定某个元素自适应,还有指定对齐方式的属性等。

Flow Layout流式布局也是非常常用,在某个方向如果元素抵达边界则自动换行,从而可以多行展示。

分层布局策略 Layered

容器被切分成多个层,每层可以容纳一个或多个元素。有两种分支:

  • Stacking 叠放 每次显示一层,可以在层之间切换,每层的元素大小相同,一般为最大的元素大小。例如CardBox卡片盒容器。

  • Overlapping Overlays 覆盖 同时显示所有层,不同层的元素之间相互覆盖。注意这种覆盖布局,只有顶层元素可以交互,而非顶层元素虽然未被顶层元素遮盖的部分可见,但不响应事件。

以下容器属于此类布局策略类型:

  • CardBox
  • TabNavigator
  • Accordion

卡片盒的行为就像是不带标签页的TabNavigator,当然实现思路有一些差异。

而手风琴则更为特殊一些,老式Windows控制面板有类似例子,后来也是经久不衰,有很多演变。

网格布局策略 Grid

将容器按照行(Row)、列(Column)交叉分割为单元格(Cell),所有元素限制在单元格内,相对单元格对齐。

  • Grid 表格 表格按照Row和Column切分,每个格子大小可以不同,由行来决定高度,由列来决定宽度。元素可以占用一个或多个Cell单元格,通过单元格的RowSpan和ColSpan来定义。

  • Tile 平铺 所有的格子总是大小相同,元素可以占用一个或多个格子。如果元素大小小于单元格,则按照定义对齐(一般是左上角对齐)单元格。平铺策略的单元格大小一般是固定或是自适应的,按照可见视图的所有元素计算出单元格大小,所有单元格保持一致大小。单元格大小确定后,元素再按照对齐定义在单元格内对齐。

容器 Containers

通用容器列表

  • Box (HBox, VBox) 线性布局,横向、纵向
  • DockPanel 停靠布局,上下左右中
  • SplitContainer 分割容器
  • CardBox 卡片盒布局,单页显示
  • Accordion 手风琴布局,单项展开
  • Grid 表格布局
  • ToolBox, ToolBar 工具盒,工具条
  • Absolute 绝对定位
  • Relative 相对定位布局
  • TileLayout 格子布局
  • Scroller 滚动条
  • SideBar 侧边栏,可以折叠
  • Disclosure / Expander (Collapsible Panel) 扩展器,点击展开、收缩的扩展区域
  • Ribbon 带子(参见Office)
  • MenuButton 菜单按钮,点击展开浮动面板

HBox & VBox - Linear 线性布局

线性布局是最常用的布局容器,横向布局使用HBox,纵向布局使用VBox。原理并不复杂,只有几条简单的规则。一个盒子可以将元素布置在两个方向之一,水平或垂直。水平盒子将它的元素进行水平排列,而垂直盒子将它的元素进行垂直排列。

代码示例

<hbox>
  <!-- horizontal elements -->
</hbox>

<vbox>
  <!-- vertical elements -->
</vbox>

<box orient="vertical">

下面例子展示怎么垂直放置三个按钮。示例代码是XUL的布局格式。

纵向并列三个按钮

<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window id="vbox example" title="Example"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

<vbox>
  <button id="yes" label="Yes"/>
  <button id="no" label="No"/>
  <button id="maybe" label="Maybe"/>
</vbox>

</window>

CSS新的FlexBox - 流式布局

CSS新标准中的FlexBox弹性容器是流式布局的一种完备实现。

输入图片说明

输入图片说明

分割容器 SplitContainer / DividedBox

一般使用一个独立的容器SplitContainer,作为一个预定义的带有分隔条的容器。其中包含两个子元素,并可以指定分隔条的方向。分隔条可以通过鼠标拖拽改变被分隔的两个区域的大小。

BoxSplitter分隔条可以放置在HBox或VBox中,自然显示为一个分隔条。 但要注意,由于线性布局可以放置多个串行元素,如果一个分隔条之后有多个元素,那么必须指定当Splitter调整位置时,哪个元素的大小将自动改变。

卡片盒 CardBox - 层叠容器

  • CardBox 每层称为Card
  • ViewStack 每层称为Frame,
  • PanelManager 每层称为Panel,

层叠容器的典型案例就是向导Wizard,点击下一步、上一步时,内容区域页面切换,同一时间只有一个页面显示。

用CardBox命名比较形象,就像一个名片盒,里面放置一张张名片,放在最上面的卡片可见。Stack原本的含义就是叠放,就像编程语言中的栈集合或栈内存,只能看到最外的一层,里面的所有层次都是在黑盒内不可见。

CardBox使用SelectedItem或SelectedIndex来访问或切换当前展示的卡片。

输入图片说明

典型案例,打印机安装向导。使用上一步、下一步来切换卡片。

输入图片说明

CardBox可以链接到Tab或一组按钮(例如RadioButton Group),点击时一对一直接切换到对应的卡片页面。

输入图片说明

表格布局 Grids / Table

基于行、列的表格布局,可以将元素按格放置。元素也可以跨行、跨列。元素根据跨行、跨列的定义决定占用的边界,在边界内根据对齐和留白的配置决定位置。

Table.Columns.Add(Column column); 
Table.Rows.Add(Row row);

表格单元格,及跨列放置按钮示意图。

输入图片说明

平铺布局 Tile Layout

下图是Flex4的TileLayout示意图。

输入图片说明

下图是一种较为复杂的网格布局,在平铺布局的基础上有所变化,类似Win8开始菜单出现的磁贴(Tiles)布局。

输入图片说明

工具盒 Toolbox, 工具条 Toolbar, 工具按钮ToolButton

一个工具盒可以容纳多个工具条,每个工具条容纳多个工具按钮

输入图片说明

锚点 Anchor Point - 相对布局 RelativeLayout

锚点布局,如图中的红色方块,设置了锚点后,当窗体大小改变时,被锚定的点会跟随拉伸。

输入图片说明

输入图片说明

停靠面板 DockPanel & 边框布局 Border Layout

两种命名方式下的五个区域名称:

  • DockPanel: Top, Right, Bottom, Left, Fill
  • BorderLayout: North, East, South, West, Center

其中,DockPanel与WinForm完美兼容。可以直接使用。

算法:用添加顺序来决定遮盖方向(每次添加时,在剩余区域内切割一块)

输入图片说明

输入图片说明

手风琴 Accordion

属于分层布局策略,每个层有横向页签展示,相互互斥,一次只展示激活的一层。

输入图片说明

带子 Ribbon

这是现代的新的页签复合样式,适合文档型程序。

输入图片说明

侧边栏 SideBar

侧边栏展示页签,高大上。

输入图片说明

扩展器 Disclosure (Expander)

可以展开折叠的区域,折叠后显示标题文本,展开时可以显示一个扩展面板。

输入图片说明

菜单按钮 MenuButton

MenuButton常见与手机界面,一个面包片按钮代表菜单,当点击时滑出菜单。

输入图片说明

圣杯布局 Holy Grail - 组合布局

圣杯布局是一种组合式布局,是扁平化的经典例子。圣杯布局首先是在网页设计上提出的。

输入图片说明

圣杯布局在不同设备(屏幕和手机)上的变化:

输入图片说明

群组容器 Grouping Container

群组容器用于逻辑上聚集一组UI元素,这些UI元素成为群组容器的子,将随着父容器改变位置、随着父容器隐藏显示改变可用性等。

群组容器其实是一个抽象容器,适合作为容器的基类。从抽象意义上来说,大部分容器都是群组容器的具象。但实际上,我们习惯将一种实线矩形框起来的容器称为群组容器。

在Windows中叫做GroupBox分组框控件。

输入图片说明

GroupBox也有很多扩展实现,包括可复选的标题、可折叠的标题等等。从这个意义上来说,手风琴控件可以看作GroupBox的一个派生类。

标签: 布局 容器 界面
共有 人打赏支持
粉丝 9
博文 8
码字总数 8893
×
炽火
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: