布局系统
每个UI界面都是由大量的界面元素构成的,在window编程中,这些界面元素的最小单位被称为控件,而布局则是这些控件在界面的相对位置和大小。
目前SOUI支持锚点布局、线性布局、网格布局,下面会依次介绍这几种布局方式。
锚点布局
所谓锚点布局,是定义了一个控件的坐标位置,这个位置往往不是一个绝对位置,而是相对于前后兄弟控件、父窗口的位置进行布局,这个位置被称为锚点,当父窗口的大小发生改变时,控件会根据该锚点的位置自动做出调整。
SOUI提供如下属性,用于支持锚点布局,分别是:pos、size、offset、width、height。
pos 属性
pos属性是锚点布局中最重要的一个属性,,可以指定2个值,也可以指定4个值,格式如下:
pos="x,y" //指定2个值 pos="left,top,right,botton" //指定4个值
当指定2个值时,代表控件左上角的位置,此时控件的大小将取决于子控件的大小,即该控件的大小将自适应。
当指定4个值时,代表该控件左上角和右下角这两个点的位置,通过这两点,即可确认一个控件的大小。
例如:<window pos="50,50,100,100" colorbkgnd="#ff0000" /><!--绘制红色控件--> <window pos="200,200" colorbkgnd="#00ff00"> <!--绘制绿色控件--> <window pos="10,10,50,50" colorbkgnd="#0000ff"/> <!--绘制蓝色控件--> </window>
这里需要注意的是,pos的第三、四参数并不是指定高度和宽度,而是界面坐标位置,高度、宽度有专门的标识符指定,后面介绍。
观察绿色和蓝色,绿色控件的高度和宽度是50,因为没有指定第三、第四参数,窗口的高度和宽度取决于子控件的大小。如果将蓝色控件删除,绿色窗口则不会展示。在子控件中,子控件是布局位置依赖父控件位置的,子控件的在界面中的位置 = 父控件位置 + 自身位置。
pos标记
pos目前支持7种标记,分别是: “|”、“%”、“[”、“]”、“{”、“}”、“@”
- “|”:代表参考父控件的中心,如“|-10”代表在父控件的中心向左/上偏移10个像素。
- “%”:代表在父控件的百分比位置,可以是小数、负数,如“%40”代表在父控件40%的位置,“%-40”则等价于1-40%。
- “[”:代表相对于前一个兄弟控件,当用于1、3参数时,参考前一个兄弟控件右边位置;当用于2、4参数时,参考前一个兄弟控件下边位置。
- “]”:代表相对于后一个兄弟控件,当用于1、3参数时,参考后一个兄弟控件左边位置;当用于2、4参数时,参考后一个兄弟控件上边位置。
- “{”:代表相对于前一个兄弟控件,当用于1、3参数时,参考前一个兄弟控件左边位置;当用于2、4参数时,参考前一个兄弟控件上边位置。
- “}”:代表相对于后一个兄弟控件,当用于1、3参数时,参考后一个兄弟控件右边位置;当用于2、4参数时,参考后一个兄弟控件下边位置。
- “@”:用于指定窗口的大小,只能出现在pos属性的第3、4参数中,用于标识窗口的高度和宽度,当值为负时,代表自动计算窗口的宽度和高度。
注意:
- “|“, "[" ,"]", "{", "}" 中指定的值可以为正或者为负,值为正时代表向右或者下偏移,值为负时代表向左或者上偏移。
- 当没有指定上述标识时,pos参数值也可取负值,负值代表参考父控件右边或者下边缩进绝对值位置,如:pos="0,0,-0,-0"代表子控件占满整个父控件,pos="10,10,-20,-20"则代表左边和上边缩进10个像素,右边和下边缩进20个像素。
- 基于前后布局,理论可能出现循环引用,导致界面布局失败,因此在使用时需要特别注意。
简单例子:
<!--基于红色窗口,在红色窗口的右上角产生一个黄色窗口--> <window pos="}0,]-50,@50,@50" offset="-0.5,-0.5" colorbkgnd="#ffff00" /> <!--在窗口中间产生一个红色控件--> <window pos="|0,|0,@50,@50" offset="-0.5,-0.5" colorbkgnd="#ff0000" /> <!--在红色窗口的右下角产生一个绿色窗口--> <window pos="[0,[0,@50,@50" colorbkgnd="#00ff00" /> <!--基于绿色窗口,在红色窗口的左下角产生一个蓝色窗口--> <window pos="{-100,{-0,@50,@50" colorbkgnd="#0000ff" /> <!--基于蓝色窗口,在红色窗口的左上角产生一个黑色窗口--> <window pos="{0,{-100,@50,@50" colorbkgnd="#000000" />
基于特定兄弟窗口的布局
在上边的用例中,除了红色窗口外,其他窗口的位置都是基于红色窗口来进行布局的,但实际代码布局逻辑却不是基于红色窗口位置来书写的。如果换做其他更加复杂的布局需求,代码将会变得异常复杂,归根结底是因为当前控件只能基于前后兄弟控件的位置布局。实际上,SOUI是支持基于特定窗口的布局。要实现该功能,方法如下:
- 被参考的控件必须指定窗口的ID属性(不能通过name属性引用)
- 在参考控件的pos属性中,使用 sib.方向@参考ID:偏移值 的方式布局
其中:
- 方向的取值为:left、right、top、bottom。
- 参考ID为:被参考窗口的ID值,这也是为什么要求被参考窗口必须指定ID属性。
- 偏移值:单位为像素,是基于方向的取值。
参考红色窗口实现上图布局:
<!--参考窗口,需指定id值--> <window pos="|0,|0,@50,@50" offset="-0.5,-0.5" id="10" colorbkgnd="#ff0000" /> <window pos="sib.left@10:-50,sib.top@10:-50,@50,@50" colorbkgnd="#000000" /> <!--左上角--> <window pos="sib.right@10:0,sib.top@10:-50,@50,@50" colorbkgnd="#00ff00" /> <!--右上角--> <window pos="sib.left@10:-50,sib.bottom@10:0,@50,@50" colorbkgnd="#0000ff" /> <!--左下角--> <window pos="sib.right@10:0,sib.bottom@10:0,@50,@50" colorbkgnd="#ffff00" /> <!--右下角-->
size、width、height 属性
size、width、height这三个属性用法比较简单,都是用来指定窗口的大小。其中,size可以指定2个参数,size="width, height"。
width、height的取值有3种:full、-1、非负整数。
- 当取值为”full“时,代表高度或者宽度占满整个父控件。
- 当取值为”-1“时,代表根据控件内容自动计算控件大小。
- 非负整数则代表窗口的指定大小。
在文本控件中,有一个maxWidth属性,用于指定文本内容的大小,其内容宽度不得超过maxWidth给定的宽度。
offset 属性
offset属性包含两个值,用于在确定窗口的位置之后,通过偏移量来最终确定窗口位置。
在前面的用例中,offset="-0.5,-0.5",即代表在确定的位置上,分别向上和向左偏移半个窗口大小单位,从而达到窗口显示在父窗口中间位置。同样,负数是向上或者向左,整数是向下或者向右偏移。
线性布局
SOUI线性目前支持两种线性布局类型:垂直线性布局,水平线性布局。该类型通过 layout 属性指定。
layout 属性
该属性用于指定布局类型,有如下取值:
- vbox 垂直线性布局。
- hbox 水平线性布局。
垂直线性布局是在垂直方向上平铺控件;水平线性布局是在水平方向上平铺控件。参考下面例子:
<window pos="5,[2,-0,-0" > <window layout="vbox" pos="0,0,150,-0" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" colorbkgnd="#ff0000" /> <window size="100,50" colorbkgnd="#00ff00" /> <text text="垂直线性布局" /> </window> <window pos="[20,0,-0,150" gravity="center" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" colorbkgnd="#ff0000" /> <window size="100,50" colorbkgnd="#00ff00" /> <text text="水平线性布局" /> </window> </window>
gravity 属性
这是一个依赖于当前布局类型的属性,用于指定对齐方式,只能用在容器窗口。
当前布局类型为垂直线性布局时,gravity属性值为:
- left(默认)
- center
- right
当前布局类型为水平线性布局时,gravity属性值为:
- top(默认)
- center
- bottom
例子如下:
<window pos="5,[2,-0,-0" > <window layout="vbox" gravity="right" pos="0,0,150,-0" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" colorbkgnd="#ff0000" /> <window size="100,50" colorbkgnd="#00ff00" /> <text text="垂直线性布局" /> </window> <window pos="[20,0,-0,150" layout="hbox" gravity="center" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" colorbkgnd="#ff0000" /> <window size="100,50" colorbkgnd="#00ff00" /> <text text="水平线性布局" /> </window> </window>
layout_gravity 属性
layout_gravity属性同样是用来指定对齐方式。gravity属性只能用于容器窗口,作用范围是该容器窗口中的所有子控件。而layout_gravity属性则是作用于特定子控件。
当前布局类型为垂直线性布局时,layout_gravity属性值为:
- left
- center
- right
当前布局类型为水平线性布局时,layout_gravity属性值为:
- top
- center
- bottom
例子如下:
<window pos="5,[2,-0,-0" > <window layout="vbox" gravity="right" pos="0,0,150,-0" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" colorbkgnd="#ff0000" /> <window size="100,50" layout_gravity="left" colorbkgnd="#00ff00" /> <text text="垂直线性布局" /> </window> <window pos="[20,0,-0,150" layout="hbox" gravity="center" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" layout_gravity="bottom" colorbkgnd="#ff0000" /> <window size="100,50" colorbkgnd="#00ff00" /> <text text="水平线性布局" /> </window> </window>
weight 属性
上面用到的例子中,子控件的大小都是固定的,在窗口大小发生改变时,子控件大小并不会跟着变动。如果需要子控件跟随窗口大小变化做出相应改变,则需使用weight属性。
weight属性的工作原理是:先计算出所有子控件的固定大小,剩下的空间根据weight属性指定的权重,将剩余大小自动分配给对应控件。假设有两个同样大小的控件,第一个控件的weight权重是2,第二个控件的weight权重是1,则第一个控件分配到的大小会是第二个控件分配到的大小的两倍。同样,如果两个控件本身大小不一致,即使权重相同,较大的控件分配到的空间也会多余较小的控件。
<window pos="0,0,-0,@200" layout="hbox" colorbkgnd="#cccccc"> <button height="50" text="我的文本较长" weight="1" /> <button height="50" text="文本" weight="1" /> <button height="50" text="我的权重较大" weight="2" /> <button height="50" text="文本" /> </window>
extend 属性组
在实际应用中,控件与控件之间的距离往往不是相连的,Soui提供了如下几个属性来设置控件的间距:
- extend:一次指定四个方向间隔,extend="extend_left,extend_top,extend_right,extend_bottom"
- extend_left:距左边n个像素
- extend_top:据上边n个像素
- extend_right:据右边n个像素
- extend_bottom:据下边n个像素
示例如下:
<window layout="vbox" pos="0,0,300,-0" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" extend="50,40,20,30" colorbkgnd="#ff0000" /> <window size="100,50" extend_bottom="40" colorbkgnd="#00ff00" /> <text text="垂直线性布局" /> </window>
extend属性组中的取值可以为负数,因此可以出现如下布局:
<window layout="vbox" pos="0,0,300,-0" colorbkgnd="#cccccc"> <window size="100,50" colorbkgnd="#000000" /> <window size="100,50" colorbkgnd="#ff0000" /> <window size="100,50" colorbkgnd="#00ff00" extend_top="-20" extend_bottom="-20" /> <text text="垂直线性布局" /> </window>
size、width、height属性
线性布局中不允许使用pos属性,如果想指定窗口的大小,需要用到size、width、height属性,有如下取值:
- 正整数:代表固定大小
- -1:代表该控件的大小依赖子控件大小
- -2:代表充满整个父控件
示例如下:
<window pos="0,0,-0,@200" layout="hbox" colorbkgnd="#cccccc"> <button size="-1,-2" text="我的文本较长" /> <button text="文本" /> <button size="-1,-1" text="文本" /> <button size="-2,-2" text="我的文本较长" /> </window>
可以看出,如果不指定size的大小,则默认取size="-1,-1"。
网格布局
在以往的布局中,想要实现行列对齐的布局其实比较复杂的。而网格布局,正是为了解决这一问题诞生的。
想要使用网格布局,需要将layout属性值指定为gridLayout。
layout="gridLayout"
columnCount、rowCount 属性
这两个属性用于指定行列数,rowCount代表行数,columnCount代表列数。
<window pos="5,[3,@350,-10" colorbkgnd="#ff0000" layout="gridLayout" columnCount="2" rowCount="2" xInterval="5" yInterval="5" xGravity="fill" yGravity="fill"> <button size="50,50" colorbkgnd="#0000000" text="1" /> <button size="50,50" colorbkgnd="#0000000" text="2" /> <button size="50,50" colorbkgnd="#0000000" text="3" /> <button size="50,50" colorbkgnd="#0000000" text="4" /> <button size="50,50" colorbkgnd="#0000000" text="5" /> <button size="50,50" colorbkgnd="#0000000" text="6" /> <button size="50,50" colorbkgnd="#0000000" text="7" /> <button size="50,50" colorbkgnd="#0000000" text="8" /> <button size="50,50" colorbkgnd="#0000000" text="9" /> </window>
上面布局中,我们指定了行列数均为2,因此会产生一个两行两列的布局。同时,多余的子控件会自动隐藏。并且,可以通过show属性和display属性可以自由控制需要展示的控件。
<button size="50,50" colorbkgnd="#0000000" text="2" show="0" display="0" /> <button size="50,50" colorbkgnd="#0000000" text="3" show="0" display="0" />
columnCount、rowCount属性并不需要全部指定,可以只指定其中一个。
<window pos="5,[3,@-1,@-1" colorbkgnd="#ff0000" layout="gridLayout" columnCount="4" xInterval="5" yInterval="5" xGravity="fill" yGravity="fill"> <button size="50,50" colorbkgnd="#0000000" text="1" /> <button size="50,50" colorbkgnd="#0000000" text="2" /> <button size="50,50" colorbkgnd="#0000000" text="3" /> <button size="50,50" colorbkgnd="#0000000" text="4" /> <button size="50,50" colorbkgnd="#0000000" text="5" /> <button size="50,50" colorbkgnd="#0000000" text="6" /> <button size="50,50" colorbkgnd="#0000000" text="7" /> <button size="50,50" colorbkgnd="#0000000" text="8" /> <button size="50,50" colorbkgnd="#0000000" text="9" /> </window> <window pos="5,[30,@-1,@-1" colorbkgnd="#ff0000" layout="gridLayout" rowCount="4" xInterval="5" yInterval="5" xGravity="fill" yGravity="fill"> <button size="50,50" colorbkgnd="#0000000" text="1" /> <button size="50,50" colorbkgnd="#0000000" text="2" /> <button size="50,50" colorbkgnd="#0000000" text="3" /> <button size="50,50" colorbkgnd="#0000000" text="4" /> <button size="50,50" colorbkgnd="#0000000" text="5" /> <button size="50,50" colorbkgnd="#0000000" text="6" /> <button size="50,50" colorbkgnd="#0000000" text="7" /> <button size="50,50" colorbkgnd="#0000000" text="8" /> <button size="50,50" colorbkgnd="#0000000" text="9" /> </window>
interval、xInterval、yInterval 属性
该属性用于指定子控件间的间距。
xGravity、yGravity、gravity属性
该属性用于指定行列对齐方式。其中:
- xGravity指定水平对齐方式,取值为left、center(默认)、right、fill。
- yGravity指定垂直对齐方式,取值为top、center(默认)、bottom、fill。
- gravity分别指定水平和垂直对齐方式,可以取left、center、right、top、bottom、fill。其中,left与top是同一值,right与bottom是同一值,当gravity="right"时,默认等价xGravity="right"、yGravity="bottom"。
fill代表子控件大小不受自身大小控制,填充整行或者整列。
例子如下:
<window pos="|0,[5" offset="-0.5,0" layout="gridLayout" xGravity="right" yGravity="bottom" columnCount="2" xInterval="5" yInterval="5" colorBkgnd="#888888"> <button size="50,100" colorbkgnd="#0000000" text="1" /> <button size="50,50" colorbkgnd="#0000000" text="2" /> <button size="100,50" colorbkgnd="#0000000" text="3" /> <button size="100,50" colorbkgnd="#0000000" text="4" /> </window>
仅指定gravity值:
<window pos="|0,[5" offset="-0.5,0" layout="gridLayout" gravity="right" columnCount="2" xInterval="5" yInterval="5" colorBkgnd="#888888"> <button size="50,100" colorbkgnd="#0000000" text="1" /> <button size="50,50" colorbkgnd="#0000000" text="2" /> <button size="100,50" colorbkgnd="#0000000" text="3" /> <button size="100,50" colorbkgnd="#0000000" text="4" /> </window>
layout_xGravity、layout_yGravity 属性
该属性不能用于容器窗口,只能用在子控件中。
该属性取值和gravity一致。
子控件的layout_xGravity和父控件的xGravity是一个主从关系。优先使用子控件指定的属性,如果子控件没有指定,则使用父窗口的属性。
例子如下:
<window pos="|0,[5" offset="-0.5,0" layout="gridLayout" columnCount="2" xInterval="5" yInterval="5" colorBkgnd="#888888"> <button size="50,100" colorbkgnd="#0000000" text="1" /> <button size="50,50" colorbkgnd="#0000000" text="2" /> <button size="100,50" colorbkgnd="#0000000" text="3" /> <button size="100,50" colorbkgnd="#0000000" text="4" /> </window> <window pos="|0,[5" offset="-0.5,0" layout="gridLayout" columnCount="2" xInterval="5" yInterval="5" colorBkgnd="#ff0000"> <button size="50,100" colorbkgnd="#0000000" text="1" /> <button size="50,50" layout_yGravity="bottom" colorbkgnd="#0000000" text="2" /> <button size="100,50" colorbkgnd="#0000000" text="3" /> <button size="100,50" colorbkgnd="#0000000" text="4" /> </window>
rowSpan、columnSpan属性
该属性不能用于容器窗口,只能用在子控件中。
用于指定行列合并。rowSpan="2" 即该控件占2行。
例子如下:
<window pos="|0,[5" offset="-0.5,0" layout="gridLayout" columnCount="2" xInterval="5" yInterval="5" colorBkgnd="#ff0000"> <button size="50,100" rowSpan="2" colorbkgnd="#0000000" text="1" /> <button size="50,50" layout_yGravity="bottom" colorbkgnd="#0000000" text="2" /> <button size="100,50" colorbkgnd="#0000000" text="3" /> <button size="100,50" colorbkgnd="#0000000" text="4" /> </window>
rowWeight、columnWeight 属性
该属性不能用于容器窗口,只能用在子控件中。
该属性类似线性布局中weight属性。
标签:控件,位置,窗口,布局,系统,指定,SOUI2,属性 From: https://www.cnblogs.com/BroccoliFighter/p/18060418