看完控件,紧接着看布局,布局是可以来放置控件,管理控件的。布局里也可以嵌套布局。
我们新建项目UILayoutTest项目,活动名和布局名选择默认。加入活动及其对应的布局已经创建完成。
- 线性布局(LinearLayout)
- android:layout_gravity属性
- android:layout_weight属性
- 相对布局(RelativeLayout)
- 相对于父布局定位
- 相对于控件定位:注意:当一个控件去引用另一个控件的id时,该控件一定要定义在引用控件的后面,不然会找不到id的情况
LinearLayout布局会将它所包含的控件在线性方向上一次排列,所谓线性方向,可能是垂直方向,或者是水平方向,前面我们都是在垂直方向上排列控件,我们可以通过android:orientation属性指定了排列方向是vertical,如果指定的是horizontal,控件就会在水平方向上排列了。修改activity_layout.xml新增加三个按钮,我们可以想不写android:orientation属性,发现3个按钮根据自身大小水平排列,因为这是LinearLayout布局默认的控件排列方式,(倘若你的第一个控件的android:layout_width="match_parent",就是说你的一个控件的宽度等于整个屏幕的宽度,那么你后面的哪个控件很有可能显示不出来。)
等到我们写过android:orientation="vertical",我们会发现3个按钮垂直的排列了。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uilayouttest.MainActivity"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 1"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 2"/><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Button 3"android:textAllCaps="false"/></LinearLayout>
这里需要注意:如果LinearLayout的排列方式是horizontal,内部的控件就不能将宽度指定为match_parent,因为这样,单独一个控件会将整个水平方向占满,其他控件就没有可以放置的位置了。同样的道理如果LinearLayout的排列方式是horizontal,内部控件就不能将高度指定为match_parent,因为这样,单独一个控件会将整个垂直方向占满。
我们首先来看布局的android:layout_gravity属性,我们之前看过android:gravity属性,这两者有些相似。区别是:android:gravity是指定文字在控件中的对齐方式,而android:layout_gravity是指定控件在布局中的对齐方式。两者的可选值差不多,但是需要注意:LinearLayout的排列方向是horizontal时,只有垂直方向上的对齐方式才会生效,因为此时水平方向的长度是不固定的,每增加一个控件,水平方向上的长度都会改变,因而无法指定该方向上的对齐方式。同样道理,当LinearLayout的排列方向是vertical时,只有水平方向上的对齐方式才会生效。修改activity_main.xml文件,代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools" android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uilayouttest.MainActivity"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="top"android:text="Button 1"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center_vertical"android:text="Button 2"/><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="bottom"android:text="Button 3"android:textAllCaps="false"/></LinearLayout>
我们再来看LineraLayout中另一个重要属性android:layout_weight。它允许我们使用比例的方式来指定控件的大小,它可以去适应手机的屏幕。下面我们来编辑一个消息发现界面,需要一个文本编辑框和一个发送按钮,修改activity_main.xml中的代码,如下所示:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uilayouttest.MainActivity"><EditTextandroid:id="@+id/input_message"android:layout_width="0dp"android:layout_height="wrap_content" android:layout_weight="3"android:hint="Type something"/><Buttonandroid:id="@+id/send"android:layout_width="0dp"android:layout_height="wrap_content" android:layout_weight="2"android:text="Send"/></LinearLayout>
发现<EditText>和<Button>的宽度都指定为了0dp,不过你不用担心文本编辑框和按钮不存在,因为我们又接着使用了android:layout_weight属性,此时控件大小由android:layout_weight来决定。这里0dp是一种比较规范的写法。另外,dp是Android中用于指定控件大小、间距等属性的单位。在这里我们把<EditText>和<Button>的android:layou_weight分别设置为3和2,这表明EditText占整个屏幕宽度的3份,Button占2份(我们是将整个屏幕分为3+2份)。
当然,我们也可以只是指定部分控件的layout_weight值来实现更好的效果。修改activity_main.xml文件中的代码,如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uilayouttest.MainActivity"><EditTextandroid:id="@+id/input_message"android:layout_width="0dp"android:layout_height="wrap_content"android:layout_weight="3"android:hint="Type something"/><Buttonandroid:id="@+id/send"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Send"/></LinearLayout>
我们只是指定了EditText的android:layout_weight属性,并将Button的宽度改为wrap_content。这表明Button的宽度仍然按照wrap_content来计算,而EditText则会占满屏幕的所有剩余空间。
- 相对布局(RelativeLayout)
- android:layout_alignParentLeft属性可以让控件和父布局的左上角对齐
- android:layout_above属性可以让一个控件位于另一个控件的上方
- android:layout_alignLeft表示让一个控件的左边缘和另一个控件的左边缘对齐
相比较LinearLayout,RelativeLayout更加随意一些,它通过相对定位的方式让控件出现在布局的任何位置。正因为如此,RelativeLayout的属性非常多,不过都是有规律可循的。修改activity_main.xml中的代码,如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uilayouttest.MainActivity"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentTop="true"android:text="button 1"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_alignParentTop="true"android:text="button 2"/><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="button 3"/><Buttonandroid:id="@+id/button4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentLeft="true"android:layout_alignParentBottom="true"android:text="button 4"/><Buttonandroid:id="@+id/button5"android:textAllCaps="false"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_alignParentBottom="true"android:layout_alignParentRight="true"android:text="button 5"/></RelativeLayout>
我们让Button 1和父布局的左上角对齐,Button 2和父布局的右上角对齐,Button 3居中显示,Button 4 和父布局的左下角对齐,Button 5 和父布局的右下角对齐。程序运行如下:
上面这是相对于父布局定位。
下面我们相对于控件进行定位。
修改activity_main.xml中的代码,如下:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:orientation="horizontal"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="com.example.uilayouttest.MainActivity"><Buttonandroid:id="@+id/button1"android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_above="@id/button3"android:layout_toLeftOf="@id/button3"android:text="button 1"/><Buttonandroid:id="@+id/button2"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_above="@id/button3"android:layout_toRightOf="@id/button3"android:text="button 2"/><Buttonandroid:id="@+id/button3"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerInParent="true"android:text="button 3"/><Buttonandroid:id="@+id/button4"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/button3"android:layout_toLeftOf="@id/button3"android:text="button 4"/><Buttonandroid:id="@+id/button5"android:textAllCaps="false"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@id/button3"android:layout_toRightOf="@id/button3"android:text="button 5"/></RelativeLayout>
其中android:layout_above属性可以让一个控件位于另一个控件的上方,需要为这个属性指定相对控件的id的引用。
android:layout_toLeftOf表示一个控件位于另一个控件的左侧。注意:当一个控件去引用另一个控件的id时,该控件一定要定义在引用控件的后面,不然会找不到id的情况。重新运行程序,如下图:
RelativeLayout中还有另外一组相对于控件进行定位的属性,android:layout_alignLeft表示让一个控件的左边缘和另一个控件的左边缘对齐,android:layout_alignRight、android:layout_alignTop、android:layout_alignBottom道理是一样的。