在博客上整理学过的东西是一种麻烦却又深刻的学习方式,原本在另一个博客写的,但是那个博客似乎不支持代码写入,也没有自动存稿,导致我一下午的成果灰飞烟灭了。反正都是学习嘛,再写一遍也无妨。
学到过的UI都需要布局,布局是为了为UI界面设定一定的结构。
Android号称四大组件,五大布局。四大组件即Activity、Service、Broadcast Receiver、Content Provider。五大布局即LinearLayout (线性布局)、RelativeLayout(相对布局)、FrameLayout(框架布局)、TableLayout(表格布局)、AbsoluteLayout(绝对布局)。那我的标题为什么说是四大布局呢?绝对布局是一种通过像素坐标确定控件位置的布局方式,其位置不可随屏幕大小不同改变,在现在这种各种 尺寸屏幕各具市场的情形下根本不适用,对于编程人员来说也是一种极大的负担,光确定控件的位置就可以是一门技术了。目前Android主流版本4.0以上,在API中绝对布局已经标识为过时的,在编写绝对布局的布局文件时,直接是预览不出效果的。绝对布局是一种通过像素坐标确定控件位置的布局方式,其位置不可随屏幕大小不同改变,在现在这种各种 尺寸屏幕各具市场的情形下根本不适用,对于编程人员来说也是一种极大的负担,光确定控件的位置就可以是一门技术了。所以我所说的四大布局是不包括绝对布局的。
Android的布局文件是XML文件,每个布局文件的根元素是一个布局,一般较常用的是线性布局和相对布局,子元素可以是布局也可以是控件,子元素布局依然可以继续嵌套布局,但是控件是不可以相互嵌套的。在叙述布局之前,有必要先陈述一下它们的属性,属性使用来设定布局或者控件的大小、位置、背景及样式的。
有些属性是布局和控件通用的:
控制大小的layout_width(宽)、layout_height(高),值可以是match_parent(填满父控件)、wrap_content(自适应),也可以是数字,单位为dp,是一种转换像素的算法得到的长度。
控制元素内容位置的gravity,值有top、bottom、left、rigth、center、center_vertical及center_horizontal,分别可以使布局或控件之内的内容处在元素内部的各个位置。
设置背景的background,值可以是16进制的颜色,格式如"#FFFFFF",也可以是引用的图片,格式如"@drawable/picture",不需要加后缀名,格式可以是jpg、png。
layout_marginTop(上外边距)、layouy_marginBottom(下外边距)、layout_marginLeft(左外边距)、layout_marginRight(右外边距)、layout_margin(四边外边距),这五个属性可以设置该控件在特定方向与相邻控件的距离,值为数字,单位dp,默认为0dp。
layout_paddingTop(上内边距)、layout_paddingBottom(下内边距)、layout_paddingLeft(左内边距)、layout_paddingRight(右内边距)、layout_padding(四边内边距),这五个属性可以设置该控件内部内容在特定方向距离控件边框的长度,值为数字,单位dp,布局中这个属性默认内容控件在左上,Button等默认内容在中间。
一些特有的属性,在实例中叙述:
1.线性布局
线性布局必须设置orientation的属性,值为horizontal或vertical,分别可将线性布局的排列方式设为水平或垂直,其他布局是不需要也不可以设置该属性的。
以下为线性布局的XML代码。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button3"
android:layout_weight="1"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button4"
android:layout_weight="1"
/>
</LinearLayout>
<Button
android:layout_width="100dp"
android:layout_height="100dp"
android:text="Button5"
android:gravity="bottom"
android:layout_gravity="right"
android:layout_margin="10dp"
/>
</LinearLayout>
效果图如下。
这里除了使用了上面提到的gravity、layout_margin外还出现了layout_gravity和layout_weight两个特殊的属性。它们是线性布局所特有的属性。首先叙述一下较简单的layout_gravity属性,值可以是top、bottom、left、rigth、center、center_vertical及center_horizontal,与gravity很相似,但layout_gravity是用来在线性布局中设置其中控件在布局中位置,只能用在线性布局内部的控件或布局属性中,其他地方是不允许的。如果orientation的值为horizontal,layout_gravity的值只能设置关于垂直方向的属性值,如果orientation的值为vertical,则layout_gravity只能设置关于水平方向的属性,不按这个规则设置不会报错但是没有效果。
layout_weight属性代表权重,值为数字,正负均可,只能在两个以上的控件间使用,按照权重值的比例为参与分配的控件(所有布局中的控件必须参与)分配屏幕特定方向的剩余空间(布局水平排列即分配屏幕宽,垂直即分配屏幕长)。所以有这样一个规律,如果参与分配的控件长宽属性设置为wrap_content,权重值越大分配到的长度就越长,权重值越小,分配到的长度就越小,但是控件不会小于自适应的大小;如果参与分配的控件长宽属性设置为match_parent,权重值越大分配到的长度越小,权重值越小,分配到的长度越大,但是控件不会超过屏幕的长或宽。为什么会这样,正是由于分配剩余空间长度的算法,若使用自适应,控件本身的长度是靠文字来确定的,这样剩余空间的长度是一个正数,控件根据自己的权重加上分配到的长度就是最后的长度;而如果是填满,控件本身的长度将都是在该方向充满屏幕长度的(当然实际情况是只有第一个控件可以显示出来),这样剩余的空间长度是一个屏幕长度减去多个屏幕长度得到的负数,为控件分配的长度即为不同权重值乘剩余空间长度,也是一个负数,原控件长度加上分配到的长度自然会出现与自适应相反的结果。
2.相对布局
相对布局中的控件必须确定自己与上一个控件的相对位置才能避免覆盖别人,第一个加入的控件不需要设置相对位置,默认为最外层布局的左上。确定相对位置的方式引用周边控件的id,格式为"@id/tv_test"。为控件设置id的方式为id="@+id/tv_test"。
确定相对位置的属性有layout_toLeftOf(在某控件左边)、layout_toRightOf(在某控件右边)、layout_above(在某控件的上方)、layout_below(在某控件下方),另外还有
layout_centerHrizontal 水平居中
layout_centerVertical 垂直居中
layout_centerInparent 相对于父控件完全居中
layout_alignParentBottom 贴紧父控件的下边沿
layout_alignParentLeft 贴紧父控件的左边沿
layout_alignParentRight 贴紧父控件的右边沿
layout_alignParentTop 贴紧父控件的上边沿
layout_alignWithParentIfMissing 若找不到兄弟元素以父元素做参照物
以上属性值都是true或者false,还有
layout_alignTop 本元素的上边沿和某元素的的上边沿对齐
layout_alignLeft 本元素的左边沿和某元素的的左边沿对齐
layout_alignBottom 本元素的下边沿和某元素的的下边沿对齐
layout_alignRight 本元素的右边沿和某元素的的右边沿对齐
以上属性亦要引用其他控件id。
相对布局的XML代码
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.briup.relativelayout.MainActivity" >
<Button
android:id="@+id/bt1"
android:layout_width="wrap_content"
android:layout_height="100dp"
android:text="Button1"
android:layout_centerInParent="true"
android:gravity="top"
/>
<Button
android:id="@+id/bt2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_toLeftOf="@id/bt1"
android:text="Button2"
android:layout_alignBaseline="@id/bt1"
/>
<Button
android:id="@+id/bt3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Button2"
android:layout_above="@id/bt1"
android:layout_toRightOf="@id/bt2"
/>
</RelativeLayout>
效果如下
这里有一个没有提到的属性layout_alignBaseline,值亦为引用其他控件id,作用是该控件与相对控件的文字下划线对齐。
3.框架布局(帧布局)
帧布局将加入的控件一个一个层叠起来,最先加入的控件在下面。
帧布局XML代码如下
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:layout_width="300dp"
android:layout_height="300dp"
android:background="#000000"
android:layout_gravity="center" />
<TextView
android:layout_width="250dp"
android:layout_height="250dp"
android:background="#092EFF"
android:layout_gravity="center"/>
<TextView
android:layout_width="200dp"
android:layout_height="200dp"
android:background="#44FF61"
android:layout_gravity="center"/>
<TextView
android:layout_width="150dp"
android:layout_height="150dp"
android:background="#FF243D"
android:layout_gravity="center"/>
<TextView
android:layout_width="50dp"
android:layout_height="50dp"
android:background="#FFFFFF"
android:layout_gravity="center"/>
</FrameLayout>
效果图如下
4.表格布局
表格布局可将控件按照表格样式排列,会按照控件最多一列使之后加入的列与其对齐,形成表格样式。
stretchColumns 设置允许被拉伸(按照最多一列对齐,如果元素不够则空开)的列的列序号
shrinkColumns 设置允许被收缩(如果内容过多,则扩展到第二行,控件没布满TableLayout时不起作用)的列的列序号
collapseColumns 设置需要被隐藏的列的列序号
多个列可以用逗号隔开,第一列为0。
表格布局XML代码如下
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:shrinkColumns="0,1,2,"
android:stretchColumns="3" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="第0列占满1行 "/>
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1111111111111111111111111111111111111111" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1111111111111111111111111111111111111111" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1111111111111111111111111111111111111111" />
</TableRow>
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2222222222222222222222222222222222222222" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="第2列占2列" />
</TableRow>
<TableRow>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="1" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="2" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="3" />
</TableRow>
</TableLayout>
效果如下