盒子
盒子
Posts List
  1. 前言
  2. 线性布局 LinearLayout
  3. 相对布局 RelativeLayout
  4. 帧布局 FramLayout
  5. 百分比布局
  6. 总结

Android 学习之路--android基础(四)

作者Talent•C
转载请注明出处

前言

一个丰富的界面总是需要有很多个控件组成,控件的基本使用我们学会了,那么我们应该如何控制这些控件的显示位置呢?这就需要使用我们今天要学习的知识了—Android的UI布局。布局是一种可以放置很多种控件的容器,它可以按照一定的规律调整内部控件的位置,从而实现精美的界面。在Android中有很多种布局方式,我们今天主要学习 四种最基本的布局

线性布局 LinearLayout

LinearLayout 又称线性布局,是一种非常常用的布局方式,正如它名字那样,将它所包含的控件按照线性的方向依次排列。我们在之前的演示工程中都是用的线性布局。线性布局分为 水平方向和竖直方向
我们创建一个工程演示一下,工程名字叫做 LayoutTest,默认的 Acitvity 名字为 HomeActivity, 对应的布局文件名为 activity_home.xml
我们打开 activity_home.xml 文件,将所有内容清空,并写入如下内容

1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/home_root" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
</LinearLayout>

我们来分析一个这个文件每行的含义,
第一行中<?xml version="1.0" encoding="utf-8"?>标准的 XML 文件格式头。第二行中的<LinearLayout>标签表示布局类型为线性布局,android:layout_width="match_parent"
android:layout_height="match_parent"表示布局的区域宽高取值与屏幕宽高一致,可选值有三种: match_parentfill_parentwrap_content。其中 match_parentfill_parent 意义相同,现在官方比较推荐我们使用 match_parent,match_parent 表示让当前控件的大小与父布局一样大小,也就是由父布局决定当前控件的大小。 wrap_content 表示让控件的大小刚好能够包含里面的内容,也就是当前控件的大小由其内容决定;所以上面的控件宽度与手机屏幕宽度一致,高度与内容高度一致。android:orientation="vertical"表示这个布局的区域的线性方向为竖直方向,有两个值可选择 horizontalvertical;horizontal 表示按照水平方向依次排列,也就是按照屏幕横向区域依次排列控件,vertical 表示按照在竖直方向上依次排列控件位置。

接下来我们来看看控件是如何设置布局的

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
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:id="@+id/home_root" xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width ="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
//创建三个按钮 在竖直方向依次排列
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_v_l_1"
android:text="按钮1"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_v_l_2"
android:text="按钮2"
/>
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button_v_l_3"
android:text="按钮3"
/>
</LinearLayout>

可以看出每个按钮都是与屏幕的宽度相同,高度与自身文字内容高度相同,这是竖直方向的线性布局,如果想在水平方向上使用线性布局将上述中 android:orientation=”vertical” 修改为 android:orientation=”horizontal” 即可。

LinearLayout线性布局的相关属性说明:

属性名 功能说明
android:orientation 布局方向:”vertical”垂直线性布局,”horizontal”水平线性布局
android:id 为控件指定相应的ID
android:text 指定控件当中显示的文字,需要注意的是,这里尽量使用strings.xml文件当中的字符
android:grivity 指定控件的基本位置,比如说居中,居右等位置
android:textSize 指定控件当中字体的大小
android:background 指定该控件所使用的背景色,RGB命名法
android:width 指定控件的宽度
android:height 指定控件的高度
android:padding 指定控件的内边距,也就是说控件当中的内容
android:singleLine 如果设置为真的话,则将控件的内容在同一行当中进行显示
android:layout_weight 默认值为0,layout_weight属性可以控制各个控件在布局中的相对大小,线性布局会根据该控件layout_weight值与其· 所处布局中所有控件layout_weight值之和的比值为该控件分配占用的区域。

注意:
如果 LinearLayout 线性布局方向为 horizontal(水平),内部空间的宽度决不能使用 match_parent 否则会导致一个控件独自占用整个屏幕的宽度,其他控件没有区域显示了。同理 vertical 时,高度也决不能使用 match_parent

如果 LinearLayout 线性布局方向为 horizontal(水平) 内部控件的 android:grivity 只有竖直方向的对齐方式才有效果,同理 vertical 时,对齐方向只有水平方向的才有效果。

相对布局 RelativeLayout

RelativeLayout(相对布局)LinearLayout 的排列规则不同,RelativeLayout 显得更加随意一些,它可以通过相对定位的方式让控件出现在布局的任何位置。

我们通过一个例子来看一下相对布局的基础用法

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
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout android:id="@+id/rela_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
//内部子控件
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_r_1"
android:layout_centerInParent="true"
android:text="按钮1"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_r_2"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:text="按钮2"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_r_3"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:text="按钮3"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_r_4"
android:layout_alignParentLeft="true"
android:layout_alignParentBottom="true"
android:text="按钮4"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/button_r_5"
android:layout_alignParentRight="true"
android:layout_alignParentBottom="true"
android:text="按钮5"
/>
</RelativeLayout>

布局文件的格式除了 <RelativeLayout> 标签与线性布局的标签不一样其余的格式完全一样,当然内部的子控件布局属性也会不一样,上述运行效果是,屏幕中心位置有一个按钮,屏幕四个角落有一个按钮,一共五个按钮。

RelativeLayout相对布局的相关属性说明:
1、相对于兄弟元素:

属性名 功能说明
android:layout_above=”@id/xxx” 在指定View的上方
android:layout_below=”@id/aaa” 在指定View的下方
android:layout_toLeftOf=”@id/bbb” 在指定View的左边
android:layout_toRightOf=”@id/cccc” 在指定View的右边

2、相对于父元素:

属性名 功能说明
android:layout_alignParentLeft=”true” 在父元素内左边
android:layout_alignParentRight=”true” 在父元素内右边
android:layout_alignParentTop=”true” 在父元素内顶部
android:layout_alignParentBottom=”true” 在父元素内底部
android:layout_alignWithParentIfMissing 如果对应的兄弟元素找不到的话就以父元素做参照物

3、对齐方式:

属性名 功能说明
android:layout_centerInParent=”true” 居中布局
android:layout_centerVertical=”true” 水平居中布局
android:layout_centerHorizontal=”true” 垂直居中布局
android:layout_alignTop=”@id/xxx” 与指定View的上边界一致
android:layout_alignBottom=”@id/xxx” 与指定View下边界一致
android:layout_alignLeft=”@id/xxx” 与指定View的左边界一致
android:layout_alignRight=”@id/xxx” 与指定View的右边界一致

4、间隔:

属性名 功能说明
android:layout_marginBottom=”” 离某元素底边缘的距离, 单位dp
android:layout_marginLeft=”” 离某元素左边缘的距离, 单位dp
android:layout_marginRight =”” 离某元素右边缘的距离, 单位dp
android:layout_marginTop=”” 离某元素上边缘的距离, 单位dp

margin 与padding 区别
padding 是站在 父View 的角度,是自己的内容与其父控件的边之间的距离。margin 则是站在自己的角度描述问题,自己与旁边的某个组件的距离,如果同一级只有一个 View ,那么它的效果基本上就和 padding 一样了。

帧布局 FramLayout

FramLayout 相对于前面两种布局方式就简单太多了,这个布局直接在屏幕上开辟出一块空白的区域,当我们往里面添加控件的时候,会默认把他们放到这块区域的左上角,而这种布局方式却没有任何的定位方式,所以它应用的场景并不多,帧布局的大小由控件中最大的子控件决定,如果控件的大小一样大的话,那么同一时刻就只能看到最上面的那个组件!后续添加的控件会覆盖前一个!虽然默认会将控件放置在左上角,但是我们也可以通过layout_gravity属性,指定到其他的位置!
代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout android:id="@+id/frame_root"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
//创建三个子控件
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/buttom_frame_1"
android:text="按钮1"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/buttom_frame_2"
android:layout_marginTop="100dp"
android:text="按钮2"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/buttom_frame_3"
android:layout_gravity="center_horizontal"
android:text="按钮3"/>
</FrameLayout>

这种布局方式只能使用一些基本的布局属性控制布局位置,如 android:layout_gravitylayout_marginTop 等。

百分比布局

前面的三种布局在 Android 1.0 版本中就开始支持了,一直沿用至今,不过对于 layout_weight 属性只有线性布局(LinearLayout)才会有,其他两种布局方式都不支持;如果想实现两个按钮平分屏幕宽度,使用后两种布局方式很难实现,为此Android引入了全新的布局方式来解决这个问题——百分比布局。在这种布局方式下我们可以不使用 match_parentwrap_content 等方式指定控件大小,而是允许直接指定控件在布局中所占的百分比,这样就是实现按百分比显示控件大小。
由于 LinearLayout 本身已经支持按比例指定控件大小了,因此百分比布局只为 FrameLayoutRelativeLayout 进行功能扩展, 提供了 PercentFrameLayoutPercentRelativeLayout 这两个全新布局,因为是新增的布局方式,Android团队 为了使低版本的Android也可使用这个布局方式,所以 Android团队 将这种布局方式定义在了 support 库中,我们只需要在项目的 build.gradle 中添加百分比布局的依赖,就能保证在Android的所有版本的兼容性了。
打开 app/build.gradle 找到 dependencies 修改如下:

1
2
3
4
5
6
7
8
9
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support.constraint:constraint-layout:1.0.2'
compile 'com.android.support:percent:24.2.1'
testCompile 'junit:junit:4.12'

上述代码片段中 compile ‘com.android.support:percent:24.2.1’ 就是添加百分比布局的依赖,当我们添加完毕时,会在上方提示我们以下内容:

Gradle files has changed since last protect sync, A project may be necessary for the IDE to work properly. Sync now

这里告诉我们自上次同步之后发生了变化,我们直接点击 Sync now 就可以了。然后 Gradle 就会进行同步,把我们新添加的百分比布局引入到工程当中。
代码示例: 四个按钮平分手机屏幕

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
<?xml version="1.0" encoding="utf-8"?>
<android.support.percent.PercentFrameLayout android:id="@+id/per_f_root"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_height="match_parent"
android:layout_width="match_parent">
//创建子控件
<Button
android:id="@+id/button_pf_1"
android:text="按钮1"
android:layout_gravity="left|top"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
/>
<Button
android:id="@+id/button_pf_2"
android:text="按钮2"
android:layout_gravity="right|top"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
/>
<Button
android:id="@+id/button_pf_3"
android:text="按钮3"
android:layout_gravity="left|bottom"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
/>
<Button
android:id="@+id/button_pf_4"
android:text="按钮4"
android:layout_gravity="right|bottom"
app:layout_widthPercent="50%"
app:layout_heightPercent="50%"
/>
</android.support.percent.PercentFrameLayout>

创建四个按钮平分整个手机屏幕,也就是每个按钮占据手机屏幕的四分一,由于 PercentFrameLayout 是后来导入的依赖库,所以这里使用 app:layout_heightPercent 等属性。百分比布局分为两种 PercentFrameLayoutPercentRelativeLayout,PercentFrameLayout 继承了 FrameLayout 的所有属性,PercentRelativeLayout 继承了 RelativeLayout 的所有属性。PercentRelativeLayoutPercentFrameLayout 用法类似这里就不过多演示,相信大家一定会举一反三的。

本分比布局相关属性说明:

属性名 功能说明
layout_widthPercent 宽度占有的百分比
layout_heightPercent 高度占有的百分比
layout_marginPercent 四周间距占有的百分比
layout_marginLeftPercent 距离左侧占有的百分比
layout_marginTopPercent 距离顶部占有的百分比
layout_marginRightPercent 距离右侧占有的百分比
layout_marginBottomPercent 距离底部占有的百分比
layout_marginStartPercent 距离顶端开始占有的百分比
layout_marginEndPercent 距离底部结束占有的百分比

总结

通过学习这篇文章,我们简单了解了Android中的UI布局方式,在使用百分比布局时一定要注意引入依赖的时候 compile ‘com.android.support:percent:24.2.1’ 千万不能因为一时大意写成 compile ‘com.android.support.percent:24.2.1’, 我就是因为不小心将 “:percent:24.2.1”写成”.percent:24.2.1” 导致编译不过去,费了好半天才找到原因, 因为是 support 中的库,所以使用的时候要用app:xxxx,而使用android:xxx 是无法调用 support 中内容的。布局标签中可以嵌套另一布局标签的,也就是布局可以嵌套布局,又一周过去了,学习的时间总是很短暂,我们会在下一篇文章中学习如何自定义控件等。
本文中使用的工程下载

支持一下
扫一扫,支持Talent•C