Android全部UI组件都继承了View类,View类有一个重要的子类:ViewGroup,但ViewGroup一般做为其余组件的容器使用。如今介绍以ViewGroup为基类派生出来的布局管理器。
java
Android的布局方式有如下几种:线性布局(Linear Layout)、表格布局(Table Layout)、帧布局(Frame Layout)、相对布局(Relative Layout)、网格布局(Grid Layout)、绝对布局(Absolute Layout)。 android
1. 线性布局(Linear Layout)
这种布局比较经常使用,也比较简单,就是每一个元素占一行,固然也可能声明为横向排放,也就是每一个元素占一列。Android的线性布局不会换行,当组件一个挨着一个排列到头以后,剩下的组件将不会被显示出来。LinearLayout能够控制各组件横向排列,也可控制组件纵向排列。(经过设置android:orientation属性控制),例如定义以下XML布局管理器,res/layout/main.xml:
ide
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button1" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button2" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button3" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button4" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button5" /> </LinearLayout>
根据上面LinearLayout的配置,以线性的方式,垂直居中放置组件,运行效果以下: 布局
4)表格布局的三种单元格设置:
a)Shrinkable:表示该列全部单元格的宽度能够被收缩。
b)Stretchable:表示该列全部单元格的宽度能够被拉伸。
c)Collapsed:表示该列全部单元格会被隐藏。
下面来看下程序示范,TableLayoutTest/res/layout/main.xml:
字体
<?xml version="1.0" encoding="utf-8"?> <TableLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:shrinkColumns="1" android:stretchColumns="2" android:collapseColumns="3"> <!-- 定义第一个表格布局,指定第2列收缩,第3列拉伸 ,第4列隐藏--> <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bn1" /> <TableRow> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bn2" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bn3" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bn4" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/bn5" /> </TableRow> </TableLayout>上面的TableLayout配置中,第一个button独自占用一行,第二列收缩,第三列拉伸,第四列隐藏了。运行效果以下:
3. 帧布局(FrameLayout)
FrameLayout直接继承自ViewGroup组件。帧布局容器为每一个加入其中的组件建立一个空白的区域,每一个子组件占据一帧,这些帧都会根据gravity属性执行自动对齐。 this
下面来看下程序示范,FrameLayoutTest/res/layout/main.xml:
spa
<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:id="@+id/view01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="320px" android:height="320px" android:background="#f00" /> <TextView android:id="@+id/view02" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="280px" android:height="280px" android:background="#0f0" /> <TextView android:id="@+id/view03" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="240px" android:height="240px" android:background="#00f" /> <TextView android:id="@+id/view01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="200px" android:height="200px" android:background="#ff0" /> <TextView android:id="@+id/view4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="160px" android:height="160px" android:background="#f0f" /> <TextView android:id="@+id/view05" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" android:width="120px" android:height="120px" android:background="#0ff" /> </FrameLayout>
上面的FrameLayout定义了6个TextView,先定义的TextView位于底部,后定义的TextView位于上层,上层的组件会覆盖下层的组件,可是因为底部的组件大,不能彻底覆盖,所以运行效果以下:
设计
4. 相对布局(Relative Layout)
RelativeLayout内的子组件老是相对兄弟组件、父组件来决定的。下面来看下RelativeLayout.LayoutParams属性:
1) 只能设置为boolean值得属性:
Android:layout_centerHorizontal 位于布局容器的水平居中
Android:layout_centerVertical 位于布局容器的垂直居中
Android:layout_centerInParent 位于布局容器的中央位置
Android:layout_alignParentBottom 与布局容器底部对齐
Android:layout_alignParentLeft 与布局容器左边对齐
Android:layout_alignParentRight 与布局容器右边对齐
Android:layout_alignParentTop 与布局容器顶端对齐
2) 只能设置为其余UI组件ID的属性:
Android:layout_toRightOf 位于给出ID组件的右侧
Android:layout_toLeftOf 位于给出ID组件的左侧
Android:layout_about 位于给出ID组件的上方
Android:layout_below 位于给出ID组件的下方
Android:layout_alignTop 位于给出ID组件的上边界对齐
Android:layout_alignBottom 位于给出ID组件的下边界对齐
Android:layout_alignLeft 位于给出ID组件的左边界对齐
Android:layout_alignRight 位于给出ID组件的右边界对齐
下面来看下程序示范,RelativeLayoutTest/res/layout/main.xml: code
<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" > <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button1" android:layout_centerInParent="true" /> <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button2" android:layout_above="@id/button1" android:layout_alignLeft="@id/button1" /> <Button android:id="@+id/button3" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button3" android:layout_below="@id/button1" android:layout_alignLeft="@id/button1" /> <Button android:id="@+id/button4" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button4" android:layout_toLeftOf="@id/button1" android:layout_alignTop="@id/button1" /> <Button android:id="@+id/button5" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/button5" android:layout_toRightOf="@id/button1" android:layout_alignTop="@id/button1" /> </RelativeLayout>
运行效果以下: xml
GridLayout是Android 4.0新增的布局管理器,GridLayout的做用相似于HTML中的table标签,它把整个容器划分红 Rows x Columns 个网格,每一个网格放置一个组件。也能够设置一个组件跨越多少列或行。
经常使用的XML属性有:
android:layout_column 设置该子组件在GridLayout的第几列
android:layout_columnSpan 设置该子组件在GridLayout横向上跨几列
android:layout_gravity 设置以何种方式占据网格空间
android:layout_raw 设置该子组件在GridLayout的第几行
android:layout_rawSpan 设置该子组件在GridLayout纵向上跨几行
下面来看下程序示范,GridLayoutTest/res/layout/main.xml:
<GridLayout 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:rowCount="6" android:columnCount="4" android:id="@+id/root" > <TextView android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="4" android:textSize="50sp" android:layout_marginLeft="4px" android:layout_marginRight="4px" android:padding="5px" android:layout_gravity="right" android:background="#eee" android:textColor="#000" android:text="0"/> <Button android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_columnSpan="4" android:text="Clear"/> </GridLayout>
注意了在建立该项目的时候,最低的API至少为14,即Android 4.0。否则GridLayout属性会报错。
GridLayoutTest/src/com/lvinliang/gridlayout/MainActivity:public class MainActivity extends Activity { GridLayout gridLayout; String[] chars = new String[] { "7", "8", "9", "÷", "4", "5", "6", "x", "1", "2", "3", "-", ".", "0", "=", "+" }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); gridLayout = (GridLayout) findViewById(R.id.root); for (int i = 0; i < chars.length; i++ ) { Button bn = new Button(this); bn.setText(chars[i]); bn.setTextSize(40); // 指定组件所在的行 GridLayout.Spec rowSpec = GridLayout.spec(i / 4 + 2); // 指定组件所在的列 GridLayout.Spec columnSpec = GridLayout.spec(i % 4); GridLayout.LayoutParams params = new GridLayout.LayoutParams(rowSpec, columnSpec); params.setGravity(Gravity.FILL); gridLayout.addView(bn, params); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } }
由上面GridLayout定义一个计算机界面,界面设计成一个6 x 4的网格,显示效果以下:
6. 绝对布局(Absolute Layout)
Android将不提供任何布局控制,而是由开发人员本身经过X坐标、Y坐标来控制组件的位置。
以下所示布局文件:
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/AbsoluteLayout01" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:id="@+id/text01" android:text="绝对布局" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_x="100dip" android:layout_y="100dip"> </TextView> </AbsoluteLayout>
不推荐使用绝对布局,由于运行Android应用的手机不一样,屏幕大小、分辨率都存在很大的差别,使用绝对布局很难兼顾屏幕大小和分辨率问题。
最后,来看下Android一些经常使用的距离单位:
px: 像素,每一个px对应屏幕上的一个点
dip或dp:一种基于屏幕密度的抽象单位。在每英寸160点的显示器上,1dip = 1px。公式:px = dip * (dpi / 160)
sp:处理字体的大小。
in: 英寸,标准长度单位。
pt: 磅,1/72英寸。