SOUI总结之窗口的布局

窗口的布局

描点布局

SOUI 的锚点布局

SOUI 布局全部采用相对坐标,由 pos,offset(pos2type), size, width,height 这几个个窗

口属性配合指定。

size, width, height 属性

size, width, height 比较简单,是用来指定窗口的大小的,只有在 pos 属性指定的值个数

不为 4 时生效。

size 是 2014 年底增加的布局属性,size="width,height"。

width, height 可以有 3 种值:full,-1,非负整数。

为 full 时,代表高度或者宽度和父窗口的客户区大小相等。

-1 代表根据窗口内容自动计算窗口大小。

非负整数直接指定窗口大小。

在图片控件中,控件是指定的皮肤默认大小。

在文本控件中,还可以指定一个 maxWidth 属性,控件是文本内容的大小,但宽度不超过

maxWidth。

pos 属性

pos 属性可以指定 4 个值,也可以指定 2 个值。指定 4 个值时,分别代表控件的

left,top,right,bottom,指定两个值时代表控件的 x,y,具体位置还依赖于另外 3 个参数。

37

指定 4 个值时,pos 目前支持 7 种标志:|,%,[,],{,},@

“|”代表参考父窗口的中心;如|-10 代表在父窗口的中心向左/上偏移 10 象素。

“%”代表在父窗口的百分比,可以是小数,负数。如:%40 代表在父窗口的 40%位

置,%-40 则等价于(1-40%)。

“[”相对于前一兄弟窗口。用于 X 时,参考前一兄弟窗口的 right,用于 Y 时参考前一兄

弟窗口的 bottom

“]”相对于后一兄弟窗口。用于 X 时,参考后一兄弟的 left,用于 Y 时参考后一兄弟的 top

“{”相对于前一兄弟窗口。用于 X 时,参考前一兄弟窗口的 left,用于 Y 时参考前一兄弟

窗口的 top

“}”相对于后一兄弟窗口。用于 X 时,参考后一兄弟的 right,用于 Y 时参考后一兄弟的

bottom

“@”标志用来指定窗口的大小,只能出现在 pos 属性的第 3,4 个值中,用来标识窗口

的宽度。当后面的值为负时,代表自动计算窗口的宽度或者高度(2015.3.3 新增加解

释)。

注:“|“, "[" ,"]", "{", "}" 中指定的值都可以为正或者负,正时向右或者下偏移,负则向

左或者上偏移。

当没有上述标志时,负号代表参考父窗口的右边或者下边缩进绝对值位置。如:

pos="0,0,-0,-0"代表占满父窗口。而 pos="10,10,-10,-10"则代表在父窗口的基础上向内

全部缩进 10 点。

@:指定窗口的 size。只能用于 x2,y2,用于 x2 时,指定窗口的 width,用于 y2 时指定窗

口的 height。注:只能为正值,负号会自动忽略。

其中“{”和“}”是 SOUI 在 DUIENGINE 的基础上新增加的布局标志(SOUI 是在

DUIENGINE 的基础上全面重构而来)。

注意!!!由于系统运行向前及向后引用,理论上有可能出来循环引用,导致界面布局失败,

因此在使用"[","{",“}” 和"]"这几个标志时需要特别注意。

当 pos 只指定了 x1,y1 时,通常需要和 offset(或者 pos2type),size(或者 width,height)配

合使用。

下面先重点介绍 offset 属性

offset 属性是 SOUI 在通过 pos 属性完成坐标定位后再将坐标进行偏移的属性。和 pos 中

一般使用象素为单位不同,offset 是以控件最后的大小为单位进行平移。

我们可以在 XML 中或者代码中使用 offset = "-0.5,-0.5"这样的形式来描述窗口的坐标平

移属性。

属性中包含两个值,分别对应 X,Y 方向的平移相对于窗口大小的倍数,一般为[-1,0]的小

数(float),当然也可以超过这个范围。

我们先看一下代码中如何实现:

class SOUI_EXP SwndLayout

{

public:

//...

float fOffsetX,fOffsetY; /**< 窗口坐标偏移量, x += fOffsetX *

//...

};

int SwndLayout::CalcPosition(LPRECT lpRcContainer,CRect &rcWindow )

{

int nRet=0;

//...

if(nRet==0)

{//没有坐标等待计算了

rcWindow.NormalizeRect();

//处理窗口的偏移(offset)属性

CSize sz = rcWindow.Size();

CPoint ptOffset;

ptOffset.x = (LONG)(sz.cx * fOffsetX);

ptOffset.y = (LONG)(sz.cy * fOffsetY);

rcWindow.OffsetRect(ptOffset);

}

return nRet;

}

SwndLayout::CalcPosition 是 SOUI 用来通过 pos 及 offset 属性计算窗口坐标的关键函

数,为了突出重点,具体的坐标计算省略了,只列出平移处理部分的代码。

可以看出,在平移处理前,首先获得窗口的 Size,再将 Size 分别乘以 fOffsetX,fOffsetY 这

两个平移系数获得在 x,y 两个方向上的平移量。

最后才是将矩形做平移处理。

注意:pos2type属性已弃用,不要去使用。

线性布局

SOUI 2.5.1.1 开始支持线性布局(LinearLayout).

要在 SOUI 布局中使用线性布局, 需要在布局容器窗口里指定布局类型为 vbox | hbox,

(vbox 为垂直线性布局, hbox 为水平线性布局).

在指定布局类型后还可以为容器窗口指定 gravity 属性, 用来指定子窗口的默认排列模式.

vbox 的 gravity 有:left(默认), center, right。

hbox 有: top(默认), center, bottom。

在线性布局中的子窗口 pos 属性没有意义, 一般直接指定 size="width,height",

width/height 值: -1 代表 wrap_content, -2 代表 match_parent

可以使用 layout_gravity 可以更改当前窗口的排列模式.

使用 extend="left,top,right,bottom", extend_left, extend_top, extend_right,

extend_bottom 来指定间距. (相当于 android 的 margin)

子窗口支持使用 weight 属性.

<!--这里演示在SOUI中使用线性布局,在window中指定layout="vbox,hbox,linearLayout"时窗口的子窗口布局变成自动布局模式-->

<window layout="vbox" size="-1,-1" colorBkgnd="#cccccc" gravity="center">

   <!--线性布局的自适应子窗口大小-->

   <text>vbox + gravity + wrapContent</text>

   <window size="100,30" colorBkgnd="#ff0000" />

   <window size="200,30" extend="10,5,10,5" colorBkgnd="#ff0000" />

   <window size="120,30" layout_gravity="right" colorBkgnd="#ff0000" />

</window>

<window pos="0,[5,@-1,@200" layout="vbox" colorBkgnd="#cccccc">

   <!--线性布局的weight属性-->

   <text extend_bottom="10">vbox + gravity + weight</text>

   <window size="100,30" colorBkgnd="#ff0000" />

   <window size="200,30" extend="10,5,10,5" colorBkgnd="#ff0000" weight="1" />

   <window size="120,30" layout_gravity="right" colorBkgnd="#ff0000" weight="1" />

   <button size="100,30" extend_top="10">button test</button>

</window>

<window pos="0,[5" layout="vbox" colorBkgnd="#cccccc" id="10000">

   <text extend_bottom="10" layout_gravity="center">hbox demo</text>

   <window size="-1,-1" layout="hbox" colorBkgnd="#888888">

      <!--线性布局之hbox-->

      <button size="100,30">button1</button>

      <button size="100,30" extend_left="10">button2</button>

      <button size="100,30" extend_left="10">button3</button>

      <button size="100,30" extend_left="10">button4</button>

   </window>

   <button size="-1,-1" padding="10,5,10,5" name="btn_open_wrap_content" extend_top="10">打开自适应大小窗口</button>

</window>

1.演示按钮如何居中

<window size="-2,30" layout="hbox">

  <window size="0,30" weight="1"/>

  <button name="btnUp"  size="50,28" extend_left="5">向上</button>

  <button name="btnDown"  size="50,28" extend_left="5">向下</button>

  <window size="0,30" weight="1"/>

</window>

解析:<window size="0,30" weight="1"/>在窗口中相当于一个可变大小的弹簧作用,在上述中两个弹簧始终在窗口的上下,所以可以让两个按钮始终处于中间状态。

  1. layout="hbox"时属性gravity="center" 是让窗口中的控件垂直居中.
  2. <window size="-2,-1" layout="hbox"  gravity="center" >必须是这个格式的时候,size="0,-2" weight="1"这两个属性配合才有效。如果是<window layout="hbox" >这种格式虽然窗口的布局也是水平布局,但不能实现size="0,-2" weight="1"两个属性。
  3. <window size="0,-2" weight="1" layout="vbox" gravity="center" extend="5,0,5,0">中gravity="center"这个属性,对<text size="-2,-1" text=""  colorText="RGB(0,0,255)"/>不起作用,原因是使用了size="-2,-1",若要起作用则改成size="70,28"。

网格布局

<window pos="10,[5,@350,-10" layout="gridLayout" columnCount="4" rowCount="6" xInterval="5" yInterval="5" xGravity="fill" yGravity="fill">

      <edit size="0,0" cueText="数值" columnSpan="4" rowWeight="2" colorBkgnd="#ffffe0ff" />

      <button size="0,0" text="清除" columnWeight="1" rowWeight="1" colorText="#0000ff" animate="1"/>

      <button size="0,0" text="后退" columnWeight="1" rowWeight="1" animate="1"/>

      <button size="0,0" text="/" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="x" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="7" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="8" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="9" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="-" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="4" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="5" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="6" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="+" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="1" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="2" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="3" columnWeight="1" rowWeight="1" animate="1"  />

      <!--//列 行权重为1-->

      <button size="0,0" text="=" rowSpan="2" columnWeight="1" rowWeight="2" animate="1" />

      <button size="0,0" text="0" columnSpan="2" columnWeight="2" rowWeight="1" animate="1" />

      <!--跨两列 自动填充 列权重2 行权重1-->

      <button size="0,0" text="." columnWeight="1" rowWeight="1" animate="1" />

      <!--列 行 权重1-->

</window>

  1. 网格布局的疑问在于size的大小不能设定。

<window size="-2,110" extend_left="2" layout="gridLayout" columnCount="7" rowCount="4"

                 xInterval="5" yInterval="11" xGravity="fill" yGravity="fill" margin="1,1,1,1" colorBorder="#ff000000">

        <check size="28,18" id="1800" focusable="0"/>

        <check size="28,18" id="1801" focusable="0"/>

        <check size="28,18" id="1802" focusable="0"/>

        <check size="28,18" id="1803" focusable="0"/>

        <check size="28,18" id="1804" focusable="0"/>

        <check size="28,18" id="1805" focusable="0"/>

        <check size="28,18" id="1806" focusable="0"/>

        <check size="28,18" id="1808" focusable="0"/>

        <check size="28,18" id="1809" focusable="0"/>

        <check size="28,18" id="1810" focusable="0"/>

        <check size="28,18" id="1811" focusable="0"/>

        <check size="28,18" id="1812" focusable="0"/>

        <check size="28,18" id="1813" focusable="0"/>

        <check size="28,18" id="1814" focusable="0"/>

        <check size="28,18" id="1816" focusable="0"/>

        <check size="28,18" id="1817" focusable="0"/>

        <check size="28,18" id="1818" focusable="0"/>

        <check size="28,18" id="1819" focusable="0"/>

        <check size="28,18" id="1820" focusable="0"/>

        <check size="28,18" id="1821" focusable="0"/>

        <check size="28,18" id="1822" focusable="0"/>

        <check size="28,18" id="1824" focusable="0"/>

        <check size="28,18" id="1825" focusable="0"/>

        <check size="28,18" id="1826" focusable="0"/>

        <check size="28,18" id="1827" focusable="0"/>

        <check size="28,18" id="1828" focusable="0"/>

        <check size="28,18" id="1829" focusable="0"/>

        <check size="28,18" id="1830" focusable="0"/>

      </window>

行列对齐

<text pos="|0,10" offset="-0.5,0" text="行列对齐" />

<window pos="|0,[5" offset="-0.5,0" layout="gridLayout" columnCount="2" xInterval="5" yInterval="5" xGravity="right" colorBkgnd="#888888">

  <text size="-1,-1">所在地:</text>

  <edit size="200,50" layout_xGravity="fill">广东 广州</edit>

  <text size="-1,-1">邮箱:</text>

  <edit size="200,-1" layout_xGravity="fill">xx@qq.com</edit>

  <text size="-1,-1">兴趣:</text>

  <edit size="200,-1" layout_xGravity="fill">看小电影</edit>

</window>

三分窗

<window size="-2,-2" layout="gridLayout" columnCount="2" xGravity="fill" yGravity="fill">

  <window size="0,0" rowSpan="2" columnWeight="1" colorBkgnd="#ff0000" />

  <window size="0,0" columnWeight="1" rowWeight="1" colorBkgnd="#00ff00" />

  <window size="0,0" columnWeight="1" rowWeight="1" colorBkgnd="#0000ff" />

</window>

root大小自动计算

<!--演示root大小自动计算,注意soui结点width,height的设置,哪一个值需要自动计算就设置为-1-->

<root size="-2,-1" layout="vbox" padding="5,5,5,5" colorBkgnd="#ffffff">

<caption size="-2,-1" colorBkgnd="#ffff00">

  <text size="-1,-1" font="bold:1" text="窗口大小自适应演示,支持左右拉伸"/>

</caption>

<window size="-2,100" layout="hbox">

  <window size="0,-2" text="水平平分窗口1" weight="1" colorBkgnd="#ff0000"/>

  <window size="0,-2" text="水平平分窗口2" weight="1" colorBkgnd="#00ff00"/>

  <window size="0,-2" text="水平平分窗口3" weight="1" colorBkgnd="#0000ff"/>

</window>

<text size="-1,-1" text="使用layout_gravity属性居中对齐" layout_gravity="center"/>

<window size="-1,-1" layout_gravity="right" extend_top="5" layout="hbox">

  <!--IDCANCEL支持enter退出窗口-->

  <button size="-1,-1" padding="10,5,10,5" id="IDOK" text="确定"/>

  <!--IDCANCEL支持esc退出窗口-->

  <button size="-1,-1" padding="10,5,10,5" extend_left="10" id="IDCANCEL" text="取消"/>

</window>

</root>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值