布局

# 垂直布局: vertical 垂直布局是一种比较简单的布局,会把在它里面的控件按照垂直方向依次摆放,如下图所示: 垂直布局: ————— | 控件1 | | 控件2 | | 控件3 | | ............ | —————— ## layout_weight 垂直布局中的控件可以通过layout_weight属性来控制控件高度占垂直布局高度的比例。如果为一个控件指定layout_weight, 则这个控件的高度=垂直布局剩余高度 * layout_weight / weightSum;如果不指定weightSum, 则weightSum为所有子控件的layout_weight之和。所谓"剩余高度",指的是垂直布局中减去没有指定layout_weight的控件的剩余高度。 例如: ```xml "ui"; ui.layout( <vertical h="100dp"> <text layout_weight="1" text="控件1" bg="#ff0000"/> <text layout_weight="1" text="控件2" bg="#00ff00"/> <text layout_weight="1" text="控件3" bg="#0000ff"/> </vertical> ); ``` 在这个布局中,三个控件的layout_weight都是1,也就是他们的高度都会占垂直布局高度的1/3,都是33.3dp. 再例如: ```xml "ui"; ui.layout( <vertical h="100dp"> <text layout_weight="1" text="控件1" bg="#ff0000"/> <text layout_weight="2" text="控件2" bg="#00ff00"/> <text layout_weight="1" text="控件3" bg="#0000ff"/> </vertical> ); ``` 在这个布局中,第一个控件高度为1/4, 第二个控件为2/4, 第三个控件为1/4. 再例如: ``` "ui"; ui.layout( <vertical h="100dp" weightSum="5"> <text layout_weight="1" text="控件1" bg="#ff0000"/> <text layout_weight="2" text="控件2" bg="#00ff00"/> <text layout_weight="1" text="控件3" bg="#0000ff"/> </vertical> ); ``` 在这个布局中,因为指定了weightSum为5, 因此第一个控件高度为1/5, 第二个控件为2/5, 第三个控件为1/5. 再例如: ```xml "ui"; ui.layout( <vertical h="100dp"> <text h="40dp" text="控件1" bg="#ff0000"/> <text layout_weight="2" text="控件2" bg="#00ff00"/> <text layout_weight="1" text="控件3" bg="#0000ff"/> </vertical> ); ``` 在这个布局中,第一个控件并没有指定layout_weight, 而是指定高度为40dp, 因此不加入比例计算,此时布局剩余高度为60dp。第二个控件高度为剩余高度的2/3,也就是40dp,第三个控件高度为剩余高度的1/3,也就是20dp。 垂直布局的layout_weight属性还可以用于控制他的子控件高度占满剩余空间,例如: ```xml "ui"; ui.layout( <vertical h="100dp"> <text h="40dp" text="控件1" bg="#ff0000"/> <text h="40dp" text="控件2" bg="#00ff00"/> <text layout_weight="1" text="控件3" bg="#0000ff"/> </vertical> ); ``` 在这个布局中,第三个控件的高度会占满除去控件1和控件2的剩余空间。 # 水平布局: horizontal 水平布局是一种比较简单的布局,会把在它里面的控件按照水平方向依次摆放,如下图所示: 水平布局: ———————————————————————————— | 控件1 | 控件2 | 控件3 | ... | ———————————————————————————— ## layout_weight 水平布局中也可以使用layout_weight属性来控制子控件的宽度占父布局的比例。和垂直布局中类似,不再赘述。 # 线性布局: linear 实际上,垂直布局和水平布局都属于线性布局。线性布局有一个orientation的属性,用于指定布局的方向,可选的值为vertical和horizontal。 例如<linear orientation="vertical"></linear>相当于<vertical></vertical>。 线性布局的默认方向是横向的,因此,一个没有指定orientation属性的线性布局就是横向布局。 # 帧布局: frame 帧布局是最简单的布局,它默认从容器的左上角(0,0)坐标开始布局,多个子控件层叠排序,后面的控件会覆盖前面的控件。 ## gravity 设置布局的默认重力位置。默认为容器的左上角。比如设置gravity="center"后,它的子控件会默认居中显示。gravity的详细字段说明参见View.gravity。 可以用layout_gravity单独控制子控件的重力,参见View.layout_gravity。 ``` "ui"; $ui.layout( //设置前景图像及它的位置 <frame gravity="left|top" foreground="@drawable/ic_android_black_48dp" foregroundGravity="right|bottom"> <img w="*" h="*" /> //text控件设置不同大小与背景色,依次覆盖 <text w="300dp" h="300dp" background="#2F2F4F" /> <text w="200dp" h="200dp" background="#FF1CAE" /> <text w="100dp" h="100dp" background="#6B4226" /> </frame> ); ``` ## foreground 设置改帧布局容器的前景图像,前景图像将永远处于帧布局最上面,不会被覆盖。foreground属性的取值可以是颜色、图片路径等,和背景bg属性类似,参见bg。 ## foregroundGravity 设置前景图像(foreground)显示的位置。属性与gravity属性相同 # 相对布局: relative ## 布局说明 android居中、纵向布局和横向布局 这里只做记录用,方便他人和自己查看 ### 一、居中 --> 相对父控件 1、LinearLayout ``` // 在父布局里水平居中: // 父布局必须拥有android:orientation="vertical"属性 android:layout_gravity="center_horizontal" // 在父布局里垂直居中: // 父布局必须应设置成android:orientation="horizontal",父布局的高度应设置为android:layout_height="fill_parent" android:layout_gravity="center_vertical" // 在父布局里居右: android:layout_gravity="right" ``` 2、RelativeLayout ``` //在父布局里水平居中: android:layout_centerHorizontal="true" //在父布局里水平居中: android:layout_centerVertical="true" //相对于父元素完全居中: android:layout_centerInparent="true" ``` ### 二、居中 --> 相对子控件 ``` //水平居中 android:gravity="center_horizontal" //垂直居中 android:gravity="center_vertical" //textview居中 android:textAlignment="center" ``` ### 三、纵向布局 ``` android:orientation:"vertical" ``` ### 四、横向布局 ``` android:orientation:"horizontal" ``` ## 以父容器作为参照物 在相对布局中,可以以父容器作为参照物来确定其他控件的位置。 ————— ————— ————— ————— ————— ————— | 控件1:左上角 | | 控件4:上居中 | | 控件7:右上角 | | 控件2:左居中 | | 控件5:(居中)| | 控件8:右居中 | | 控件3:左下角 | | 控件6:下居中 | | 控件9:右下角 | ————— ————— ————— ————— ————— ————— 在以父容器作为参照物中,属性如下: layout_alignParentLeft="true" 以父容器为参照物,使控件贴在父容器的左边。 layout_alignParentRight="true" 以父容器为参照物,使控件贴在父容器的右边。 layout_alignParentTop="true" 以父容器为参照物,使控件贴在父容器的顶部。 layout_alignParentBottom="true" 以父容器为参照物,使控件贴在父容器的底部。 layout_centerHorizontal="true" 以父容器为参照物,使控件在父容器的水平方向居中。 layout_centerVertical="true" 以父容器为参照物,使控件在父容器的垂直方向居中。 layout_centerInParent="true" 以父容器为参照物,使控件在父容器的水平、垂直方向都居中。 可以通过这6个属性的组合让控件处于父容器的左上角、右上角、左下角、右下角、上居中、下居中、左居中、右居中、正居中的位置。例如给一个控件添加layout_alignParentLeft="true"和layout_alignParentBottom="true"属性后,该空间将以父容器为参照物,使控件位于父容器的左下角。 示例: ``` "ui"; $ui.layout( <relative> <button text="居中" layout_centerInParent="true"/> <button text="左上角" layout_alignParentLeft="true" layout_alignParentTop="true" /> <button text="右上角" layout_alignParentRight="true" layout_alignParentTop="true" /> <button text="左下角" layout_alignParentLeft="true" layout_alignParentBottom="true"/> <button text="右下角" layout_alignParentRight="true" layout_alignParentBottom="true"/> <button text="上居中" layout_alignParentTop="true" layout_centerHorizontal="true"/> <button text="下居中" layout_alignParentBottom="true" layout_centerHorizontal="true" /> <button text="左居中" layout_alignParentLeft="true" layout_centerVertical="true"/> <button text="右居中" layout_alignParentRight="true" layout_centerVertical="true"/> </relative> ); ``` ## 以兄弟控件作为参照物 在相对布局中,以兄弟控件(已经确定好位置的控件)作为参照物来确定其他控件的位置。 ————— ————— ————— ————— ————— ————— | 控件2:左上角 | | 控件5:正上方 | | 控件7:右上角 | | 控件3:正左方 | | 控件1:基准兄弟控件| | 控件8:正右方 | | 控件4:左下角 | | 控件6:正下方 | | 控件9:右下角 | ————— ————— ————— ————— ————— ————— 在以兄弟控件(button1)作为参照物中,属性如下: layout_toRightOf="@+id/button1" 以兄弟控件(button1)作为参照物,使控件在兄弟控件button1的下方。 layout_toRightOf="@+id/button1" 以兄弟控件(button1)作为参照物,使控件在兄弟控件button1的右方。 layout_above="@+id/button1" 以兄弟控件(button1)作为参照物,使控件在兄弟控件button1的上方。 layout_below="@+id/button1" 以兄弟控件(button1)作为参照物,使控件在兄弟控件button1的下方。 layout_alignLeft="@+id/button1" 以兄弟控件(button1)作为参照物,使控件与兄弟控件button1的左方平齐。 layout_alignRight="@+id/button1" 以兄弟控件(button1)作为参照物,使控件与兄弟控件button1的右方平齐。 layout_alignTop="@+id/button1" 以兄弟控件(button1)作为参照物,使控件与兄弟控件button1的上方平齐。 layout_alignBottom="@+id/button1" 以兄弟控件(button1)作为参照物,使控件与兄弟控件button1的下方平齐。 可以通过这8个属性的组合让控件处于兄弟控件的左上角、右上角、左下角、右下角、正上方、正下方、正左方、正右方等位置。例如给一个控件添加layout_toRightOf="@+id/button1"和layout_above="@+id/button1"属性后,该空间将以兄弟控件为参照物,使控件位于兄弟控件的右上角(两个控件的右侧边缘在同一垂线)。 相对布局里以兄弟控件为参照物确定控件的位置的示例如下: ``` "ui"; $ui.layout( <relative> <button id="button1" text="控件1:兄弟控件" layout_centerInParent="true"/> <button text="左上角" layout_above="@+id/button1" layout_toLeftOf="@+id/button1"/> <button text="右上角" layout_above="@+id/button1" layout_toRightOf="@+id/button1"/> <button text="左下角" layout_below="@+id/button1" layout_toLeftOf="@+id/button1"/> <button text="正上方" layout_above="@+id/button1" layout_alignLeft="@+id/button1"/> <button text="正下方" layout_below="@+id/button1" layout_alignLeft="@+id/button1"/> <button text="右下角" layout_toRightOf="@+id/button1" layout_below="@+id/button1" /> <button text="正左方" layout_alignTop="@+id/button1" layout_toLeftOf="@+id/button1"/> <button text="正右方" layout_toRightOf="@+id/button1" layout_alignTop="@+id/button1"/> </relative> ); ``` ## 布局模板(APP自带例子) ```js "ui"; var InputLayout = (function() { //继承至ui.Widget util.extend(InputLayout, ui.Widget); function InputLayout() { ui.Widget.call(this); this.defineAttr("hint", (view, attr, value, defineSetter)=>{ view._hint.setText(value); }); this.defineAttr("text", (view, attr, value, defineSetter)=>{ view._input.setText(value); }); } InputLayout.prototype.render = function() { return ( <vertical> <text id="_hint" textSize="16sp" margin="4" textColor="gray"/> <input id="_input" margin="0 16"/> </vertical> ); } InputLayout.prototype.getInput = function() { return this.view._input.getText(); }; ui.registerWidget("input-layout", InputLayout); return InputLayout; })(); ui.layout( <vertical> <input-layout id="name" hint="请输入名字"/> <input-layout id="age" hint="请输入年龄" text="18"/> <button id="ok" text="确认"/> </vertical> ); ui.ok.on("click", function(){ toast("名字是:" + ui.name.widget.getInput() + ", 年龄是:" + ui.age.widget.getInput()); }); ``` ### 动态显示隐藏布局内容 > 非官方例子 ```js "ui"; ui.layout( <vertical > <linear gravity="center"> <button id="bt" text="隐藏" textSize="20sp"/> </linear> <linear id="h" gravity="center"> <scroll> <text id="data" text="我出来了" textSize="20sp"/> </scroll> </linear> </vertical> ); threads.start(function() { var str=""; //遍历ui.h对象 for (var i in ui.h) { //打印对象值 str+=i+" "; } ui.data.setText(str); }); ui.bt.click(() => { if (ui.bt.getText() == "隐藏") { ui.bt.setText("显示"); ui.h.visibility = 8; toast("内容已隐藏!"); } else { ui.bt.setText("隐藏"); ui.h.visibility = 0; toast("内容已显示!"); } }); ```