Android常用布局
Android开发学习笔记——常用布局
目前Android开发过程我们总是需要使用到各种布局来构建界面,其中主要有LinearLayout(线性布局)、RelativeLayout(相对布局)、FrameLayout(帧布局)、AbsoluteLayout(绝对布局)、TableLayout(表格布局)以及官方在16年新出的布局ConstraintLayout(约束布局)等。接下来,我将对这些布局进行一个详细的说明。
LinearLayout——线性布局
LinearLayout是我们在开发过程中最常用的布局之一,从线性布局的字面意义上我们即可理解为这是一个将子控件水平或垂直线性排列的布局。
1、orientation(方向)
对于线性布局而言,首先我们需要在使用前确定其子控件的排列方向。在线性布局中,我们可以选择水平方向(horizontal)和竖直方向(vertical)排列,在xml中,我们可以使用orientation属性来进行设置。默认为水平方向排列。
android:orientation="vertical" //垂直排列
android:orientation="horizontal" //水平排列
2、gravity和layout_gravity(位置)
在LinearLayout中,布局中的子控件默认是从左上角依次进行水平排列或者垂直排列的。此时,如果需要改变子控件的排列位置,我们可以通过LinearLayout中的gravity或者是子控件的layout_gravity来进行修改。
在线性布局中,gravity属性用于指定其布局中子控件的位置。
android:gravity="center"
其常用属性值包括以下几个:
属性 | 含义 |
---|---|
center | 子控件居中 |
center_horizontal | 子控件水平居中 |
center_vertical | 子控件垂直居中 |
start/end | 子控件居开始/结束位置 |
left/right | 子控件居左部/右部位置 |
top/bottom | 子控件居顶部/底部 |
在使用gravity属性时可以使用"|"符号来同时指明两个属性,如:
android:gravity="center_horizongtal | top" //子控件位于底部水平居中
gravity属性可以指定布局中所有子控件的位置,但是如果我们需要特定布局中某个子控件的位置呢?此时,我们就需要使用到子控件中的layout_gravity属性了,该属性可以指定子控件相对于父布局的位置,可以选择的值于gravity完全相同,且也能够同时选择多个值。如下:
<?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:orientation="vertical"
android:gravity="center_horizontal">
<Button
android:text="button1"
android:layout_gravity="start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:text="button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
此时,布局显示如下图所示:
由此可见,layout_gravity在与gravity发生冲突时,是使用layout_gravity效果的。值得注意的是,在LinearLayout为水平布局时,layout_gravity只能设置子控件在竖直方向上的位置,设置如center_horizontal是无效的;同样的,垂直排列时设置竖直方向是无效的。
3、layout_weight(权重)
在LinearLayout中,layout_weight是一个很重要的属性,指定了子控件占父布局剩余屏幕大小的权重,能够很灵活地控制控件的大小,同时也能够更好地进行适配。其子控件实际大小的计算公式如下:
父布局剩余大小=父布局大小-所有控件初始大小
控件权重=控件声明权重/所有控件声明权重之和(若LinearLayout声明weightSum则等于控件声明权重/weightSum)
控件实际大小=控件声明大小+父布局剩余大小*控件权重
谷歌推荐设置控件的初始化大小为0dp,这样根据公式,即可使控件大小完全满足之间的比例,如将两个textview按照1:2划分屏幕。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:text="textview1"
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:background="@color/colorAccent"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@color/colorPrimaryDark"
android:text="textview2"
android:textColor="#FFFFFF" />
</LinearLayout>
而如果,在布局中对子控件的大小进行了初始化,那么此时会先减去控件的初始化大小,然后再对子控件的大小根据比例进行分配。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:text="textview1"
android:layout_width="100dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:background="@color/colorAccent"/>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="2"
android:background="@color/colorPrimaryDark"
android:text="textview2"
android:textColor="#FFFFFF" />
</LinearLayout>
由图可见,textview1是比textview2的宽度要大的,根据公式,我们可知,这是因为确定大小时会先为textview1分配100dp,然后再按照1:2的比例进行分配。
当然,也可能并非所有的控件都需要指定layout_weight,此时,会先减去确定大小的控件,然后再确定大小。比如,有一个常见场景为在同一行中,textview1大小确定,textview2填充剩下布局。
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:text="textview1"