布局分为:FrameLayout(帧布局,框架布局),Linearlayout(线性布局),AbsoluteLayout(绝对布局),RelativeLayout(相对布局),TableLayout(表格布局)。
它们的绘制效率对比,相同层级来讲,FramenLayout效率最高,以下依次是LinearLayout,RelativeLayout,TableLayout。而AbsoluteLayout已经不用了,就不管了。
对于绘制效率,重点区分Linearlayout和Relativelayout。它们的layout和draw的过程时间消耗相差无几,关键在于measure过程RelativeLayout比LinearLayout慢了一些,因为它需要横向纵向分别进行一次排序测量。而Linearlayout则根据orientation属性进行一次绘制就可以了。但是,如果LinearLayout使用了weight属性,也会导致两次的measure绘制。
FrameLayout
最简单的布局,它并没有对Child View的摆布进行控制,所有的子元素(控件或布局)都会默认在试图的左上角,后面的元素会覆盖前面的元素,可通过android:layout_margin,android:layout_gravity
等属性去控制子元素相对布局的位置。
Linearlayout
子元素(控件或布局)会按照水平或竖直的方向依次按顺序排列。可通过android:orientation=“horizontal|vertical
属性来控制排列的方向。
注:
- 当
android:orientation="horizontal"
时,其子元素的android:layout_gravity="right|left"
等控制水平方向的gravity值都是被忽略的,此时子元素都是默认的按照水平从左向右来排列,我们可以用android:layout_gravity="top|bottom"
等gravity值来控制垂直展示。反之亦然。
android:layout_weight属性
:表示权重,子元素占据的空间大小比例。数值越大,占据的空间越大。常用来实现等比例分配控件或布局。
示例:等比例分配布局
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="1"/> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="2"/> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="3"/> </LinearLayout>
|
示例:也可用来实现,占满剩余的空间。因为线性布局的特性,如果是水平方向的排列,则此控件相对于父布局的控制左右位置的属性是无效的,所以如果想让一个控件位于最右侧,可以让前一个控件占满剩余空间。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <!--左部按钮--> <Button android:gravity="center" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="left"/> <TextView android:gravity="center" android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:text="center"/> <!--右侧按钮--> <Button android:gravity="center" android:layout_width="wrap_content" android:layout_height="match_parent" android:text="right"/> </LinearLayout> <!--分割线--> <View android:layout_width="match_parent" android:layout_height="1dp" android:background="#e5e5e5" /> <LinearLayout android:layout_width="match_parent" android:layout_height="40dp" android:orientation="horizontal"> <!--Space控件是在Android 4.0中加入,是个空白的view。--> <!--Space控件在布局中只占位置,而不去绘制渲染。--> <!--组件中的间隙用Space控件填充比用其它控件填充可以提高绘制效率。--> <Space android:layout_width="50dp" android:layout_height="match_parent" /> <TextView android:layout_width="0dp" android:layout_weight="1" android:layout_height="match_parent" android:gravity="center" android:background="@color/red"/> <Space android:layout_width="50dp" android:layout_height="match_parent" /> </LinearLayout>
|
图例:
AbsoluteLayout
可以放置多个控件,并且可以自己定义控件的x,y位置。但已经不用了。
RelativeLayout
Android对该布局的child view的水平layout和垂直layout做了解析。它会按照子元素的相对位置关系完成布局。也是Google推荐的布局,相较于Linearlayout,它更为灵活,非常适合一些比较复杂的界面设计。对于绘制效率来讲,Linearlayout只需绘制一次(但是,如果使用了weight属性,也会导致两次measure),而RelativeLayout则需要对横向和竖向进行两次绘制。
注:在对控件定位时,需要已知相对控件的id。
相关属性:
属性 |
含义 |
示例 |
layout_toLeftOf |
位于引用组件的左方 |
android:layout_toLeftOf="@id/tv_center" |
layout_toRightOf |
位于引用组件的右方 |
android:layout_toRightOf="@id/tv_center" |
layout_above |
位于引用组件的上方 |
android:layout_above="@id/tv_center" |
layout_below |
位于引用组件的下方 |
android:layout_below="@id/tv_center" |
layout_alignParentLeft |
是否对齐父组件的左端 |
android:layout_alignParentLeft="true" |
layout_alignParentRight |
是否对齐父组件的右端 |
android:layout_alignParentRight="true" |
layout_alignParentTop |
是否对齐父组件的顶部 |
android:layout_alignParentTop="true" |
layout_alignParentBottom |
是否对齐父组件的底部 |
android:layout_alignParentBottom="true" |
layout_centerInParent |
是否相对于父组件居中 |
android:layout_centerInParent="true" |
layout_centerHorizontal |
是否横向居中 |
android:layout_centerHorizontal="true" |
layout_centerVertical |
是否垂直居中 |
android:layout_centerVertical="true" |
layout_alignLeft |
左侧相对于给定ID组件的左侧 |
android:layout_alignLeft="@id/tv_center" |
layout_alignRight |
右侧相对于给定ID组件的右侧 |
android:layout_alignRight="@id/tv_center" |
layout_alignTop |
顶部相对于给定ID组件的顶部 |
android:layout_alignTop="@id/tv_center" |
layout_alignBottom |
底部相对于给定ID组件的底部 |
android:layout_alignBottom="@id/tv_center" |
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| <RelativeLayout android:layout_width="match_parent" android:layout_height="match_parent" > <!--相对控件--> <TextView android:background="@color/red" android:id="@+id/tv_center" android:layout_margin="20dp" android:layout_centerInParent="true" android:layout_width="200dp" android:layout_height="100dp" /> <!--位于center的左侧--> <TextView android:layout_centerInParent="true" android:layout_toLeftOf="@id/tv_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toLeftOf"/> <!--位于center的右侧--> <TextView android:layout_centerInParent="true" android:layout_toRightOf="@id/tv_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="toRightOf"/> <!--位于center的上方--> <TextView android:layout_centerInParent="true" android:layout_above="@id/tv_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="above"/> <!--位于center的下方--> <TextView android:layout_centerInParent="true" android:layout_below="@id/tv_center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="below"/> <!--左侧相对于center的左侧对齐,并相对于父布局垂直居中--> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="alignLeft" android:textColor="@color/white" android:layout_centerVertical="true" android:layout_alignLeft="@id/tv_center"/> <!--右侧相对于center的右侧对齐,并相对于父布局垂直居中--> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="alignRight" android:textColor="@color/white" android:layout_centerVertical="true" android:layout_alignRight="@id/tv_center"/> <!--顶部相对于center的顶部对齐,并相对于父布局水平居中--> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="alignTop" android:textColor="@color/white" android:layout_centerHorizontal="true" android:layout_alignTop="@id/tv_center"/> <!--底部相对于center的底部对齐,并相对于父布局水平居中--> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="alignBottom" android:textColor="@color/white" android:layout_centerHorizontal="true" android:layout_alignBottom="@id/tv_center"/> <!--位于center内部的左上方--> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tv_center" android:layout_alignTop="@id/tv_center" android:text="内左上" android:gravity="center" android:textColor="@color/white"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@id/tv_center" android:layout_alignTop="@id/tv_center" android:text="内右上" android:gravity="center" android:textColor="@color/white"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignLeft="@id/tv_center" android:layout_alignBottom="@id/tv_center" android:text="内左下" android:gravity="center" android:textColor="@color/white"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignRight="@id/tv_center" android:layout_alignBottom="@id/tv_center" android:text="内右下" android:gravity="center" android:textColor="@color/white"/> <!--位于center外部的左上方--> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/tv_center" android:layout_toLeftOf="@id/tv_center" android:text="外左上"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_above="@+id/tv_center" android:layout_toRightOf="@id/tv_center" android:text="外右上"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tv_center" android:layout_toLeftOf="@id/tv_center" android:text="外左下"/> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tv_center" android:layout_toRightOf="@id/tv_center" android:text="外右下"/> </RelativeLayout>
|
图例:
示例:RelativeLayout的等比例分配空间。复杂的还是推荐使用Linearlayout来实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp"> <View android:layout_toLeftOf="@id/line" android:layout_width="match_parent" android:layout_height="match_parent" android:background="@color/red"/> <!--参照物,以它分割--> <Space android:id="@+id/line" android:layout_centerHorizontal="true" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <View android:layout_toRightOf="@id/line" android:layout_width="match_parent" android:layout_height="match_parent" /> </RelativeLayout>
|
TableLayout
表格布局,适用于多行多列的布局格式。它将子元素的位置分配到行或列中,一个TableLayout由许多的TableRow组成。
一个TableRow就表示TableLayout中的每一行,这一行可以由多个子元素组成。
实际上TableLayout和TableRow都是LineLayout线性布局的子类。但是TableRow的参数android:orientation属性值固定为horizontal,且android:layout_width=MATCH_PARENT,android:layout_height=WRAP_CONTENT。所以TableRow实际是一个横向的线性布局,且所以子元素宽度和高度一致。
注意:在TableLayout中,单元格可以为空,但是不能跨列,意思是只能不能有相邻的单元格为空。
在TableLayout布局中,一列的宽度由该列中最宽的那个单元格指定,而该表格的宽度由父容器指定。可以为每一列设置以下属性:
- Shrinkable 表示该列的宽度可以进行收缩,以使表格能够适应父容器的大小
android:shrinkColumns=”0,1,2” // 设置三列都可以收缩
- Stretchable 表示该列的宽度可以进行拉伸,以使能够填满表格中的空闲空间
android:stretchColumns = “0,1,2,3”// 设置三列都可以拉伸 如果不设置这个,那个显示的表格将不能填慢整个屏幕
- Collapsed 表示该列会被隐藏
android:collapseColumns
示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| <TableLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:shrinkColumns="0,1,2" android:stretchColumns="0,1,2"> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:gravity="center" android:padding="10dp" android:text="Button1"> </Button> <Button android:gravity="center" android:padding="10dp" android:text="Button2"> </Button> <Button android:gravity="center" android:padding="10dp" android:text="Button3"> </Button> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:gravity="center" android:padding="10dp" android:text="Button4"> </Button> <Button android:gravity="center" android:padding="10dp" android:text="Button5"> </Button> </TableRow> <TableRow android:layout_width="match_parent" android:layout_height="wrap_content"> <Button android:gravity="center" android:padding="10dp" android:text="Button6"> </Button> <Button android:gravity="center" android:padding="10dp" android:text="Button7"> </Button> <Button android:gravity="center" android:padding="10dp" android:text="Button8"> </Button> </TableRow> </TableLayout>
|
常用属性
属性 |
含义 |
示例 |
id |
控件id |
android:id="@+id/id" |
layout_margin |
外边距 |
android:layout_margin="20dp" |
padding |
内边距 |
android:padding="20dp" |
layout_gravity |
本身相对于父布局位置 |
android:layout_gravity="center" |
gravity |
子元素相对于本身的位置 |
android:gravity="center" |
background |
设置背景,图片或者颜色 |
android:background="@color/red" android:background="@mipmap/ic_launcher" android:background="#00ff00" |
visibility |
是否显示布局 |
android:visibility="invisible" |