安卓布局

线性布局

LinearLayout里面可以放置多个view(这里称为子view,子项)。

子view可以是TextView,Button,或者是LinearLayout,RelativeLayout等等。

它们将会按顺序依次排布为一列或一行。 接下来介绍一些在xml中的设置。

先在xml中放一个LinearLayout。

1
2
3
4
5
<LinearLayout 
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>

属性

竖直排布与水平排布

通过设置orientation来确定水平或竖直排布子view。 可选值有vertical和horizontal

竖直排布

设置orientation为vertical。

1
android:orientation="vertical"
水平排布

设置orientation为horizontal。

1
android:orientation="horizontal"

排布方式 gravity

决定子view的排布方式。 gravity 有“重力”的意思,我们引申为子view会向哪个方向靠拢。 gravity

有几个选项可以选择,我们常用的有start,end,left,right,top,bottom。

例如

1
2
3
4
5
6
<LinearLayout 
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="start"
android:orientation="vertical">
</LinearLayout>

下面是gravity的选项。我们会把LinearLayout叫做“父view”或者“容器”。

常量 定义值 描述
top 30 把view推到容器里的顶部。不会改变view的尺寸。
bottom 50 把view推到容器的底部。不会改变view的尺寸。
center 11 子view水平与竖直都居中。不会改变view的尺寸。
center_horizontal 1 子view水平居中。不会改变view的尺寸。
center_vertical 10 子view垂直居中。不会改变view的尺寸。
start 800003 把view推到容器里最开始的地方。不会改变view的尺寸。
end 800005 把子view放到容器的最尾部。不改变view的尺寸。
left 3 子view从容器的左边开始排布。不会改变view的尺寸。

start和left,end和right并不一定是同样的效果。

对于RTL(right to left)类型的手机,比如某些阿拉伯文的系统。start是从右到左的。

我们日常生活中很少见到RTL,一般都是LTR。但还是建议多用start而不是left。

gravity可以同时设置多个值,用或符号 | 来连接。比如

android:gravity="end|center_vertical"

1
2
3
4
5
6
<LinearLayout 
android:layout_width="match_parent"
android:layout_height="60dp"
android:gravity="end|center_vertical"
android:orientation="vertical">
</LinearLayout>
image-20220607214935550
image-20220607214940327

子 view 的 layout_gravity

layout_gravity看起来和gravity有些相似。

  • android:gravity 控制自己内部的子元素。

  • android:layout_gravity 是告诉父元素自己的位置。

取值范围和gravity是一样的。代表的含义也相似。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<LinearLayout 
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:background="#90CAF9"
android:text="none" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:background="#9FA8DA"
android:text="center" />

</LinearLayout>
image-20220607215325445
image-20220607215328843

分割占比 layout_weigh

可以在设置子view的layout_weight,来确定空间占比。 设置layout_weight 的时候,一般要设置

layout_width="0dp"

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
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#FFCC80"
android:orientation="horizontal">

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#eaeaea"
android:gravity="center"
android:text="1" />

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:text="2" />

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#eaeaea"
android:text="1" />

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="3"
android:background="#BEC0D1"
android:text="3" />

</LinearLayout>
image-20220607220027225

分割占比之和 weightSum

android:weightSum= xxx

定义子view的weight之和的最大值。如果不直接指定,它会是所有子view的layout_weight 之和。 如果想给单独的一个子view一半的空间占比,可以设置子view的layout_weight 为0.5,并且设置LinearLayout的weightSum为1.0。

取值可以是浮点数,比如 9.3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:background="#4DB6AC"
android:weightSum="9.3"
android:orientation="horizontal">

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="4.6"
android:background="#eaeaea"
android:gravity="center"
android:text="4.6" />

<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:background="#7986CB"
android:layout_weight="2.5"
android:text="2.5" />

</LinearLayout>

相对布局

简述

RelativeLayout和LinearLayout类似,都是ViewGroup,能“容纳”多个子view。

RelativeLayout 是一个以相对位置显示子视图的视图组。

每个视图的位置可以指定为相对于同级元素的位置(例如,在另一个视图的左侧或下方)或相对于父RelativeLayout区域的位置(例如在底部、左侧或中心对齐)。子view可以是TextView,Button,或者是LinearLayout,RelativeLayout等等。 如果不添加其他配置,它们默认是在RelativeLayout的左上角。 在RelativeLayout中,子View可以根据另一个子View来确定位置。 但必须注意的是,RelativeLayout和它的子View不能互相依赖。比如RelativeLayout设置wrap_content,子View设置了ALIGN_PARENT_BOTTOM,这样你会发现RelativeLayout被撑到最大。RelativeLayout能消除嵌套视图组并使布局层次结构保持扁平化。接下来介绍一些在xml中的设置。

属性介绍

RelativeLayout 可以指定子视图相对于父视图或彼此(由 ID 确定)的位置。

因此,您可以按照右边框对齐两个元素,或者使它们一上一下,屏幕居中,左侧居中,等等。默认情况下,所有子视图均绘制在布局的左上角,因此您必须使用 RelativeLayout.LayoutParams 中提供的各种布局属性定义每个视图的位置。

有很多布局属性可用于 RelativeLayout 中的视图,部分示例包括:

  • android:layout_alignParentTop

    • 如果为 "true",会将此视图的上边缘与父视图的上边缘对齐。
  • android:layout_centerVertical

  • 如果为 "true",会将此子级在父级内垂直居中。

  • android:layout_below

    • 将此视图的上边缘放置在使用资源 ID 指定的视图下方。
  • android:layout_toRightOf

    • 将此视图的左边缘放置在使用资源 ID 指定的视图右侧。
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
<RelativeLayout 
android:layout_width="match_parent"
android:layout_height="100dp">

<TextView
style="@style/RelativeLayoutDemo1Item"
android:text="default" />

<TextView
style="@style/RelativeLayoutDemo1Item"
android:layout_alignParentEnd="true"
android:text="layout_alignParentEnd" />

<TextView
style="@style/RelativeLayoutDemo1Item"
android:layout_centerInParent="true"
android:text="layout_centerInParent" />

<TextView
style="@style/RelativeLayoutDemo1Item"
android:layout_alignParentBottom="true"
android:text="layout_alignParentBottom" />

<TextView
style="@style/RelativeLayoutDemo1Item"
android:layout_alignParentEnd="true"
android:layout_alignParentBottom="true"
android:text="layout_alignParentBottom | End" />

</RelativeLayout>
image-20220608172142505
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
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="120dp">

<TextView
android:id="@+id/tv1"
style="@style/RelativeLayoutDemo1Item"
android:text="R" />

<TextView
android:id="@+id/tv2"
style="@style/RelativeLayoutDemo1Item"
android:layout_below="@id/tv1"
android:layout_toEndOf="@id/tv1"
android:text="u" />

<TextView
android:id="@+id/tv3"
style="@style/RelativeLayoutDemo1Item"
android:layout_below="@id/tv2"
android:layout_toEndOf="@id/tv2"
android:text="s" />

<TextView
android:id="@+id/tv4"
style="@style/RelativeLayoutDemo1Item"
android:layout_below="@id/tv3"
android:layout_toEndOf="@id/tv3"
android:text="t" />

</RelativeLayout>

image-20220608172411613

所有布局属性详见 View.MeasureSpec | Android Developers (google.cn)

这里只介绍了其中的两个布局