首页 > 代码库 > 第三章 界面UI的基石—UI布局(2)

第三章 界面UI的基石—UI布局(2)

3.2 百花齐放—各种Layout布局

3.2.1Layout布局的简单介绍

一般的,一个Android视图中会有很多的控件。为了界面的合理、美观,我们需要让它们按照我们设计好的思路排列在界面上,那么,我们就需要容器来存放这些控件,并控制它们的位置排列,就像HTML中的div、table一样,Android布局也起到了同样的作用。

Android布局有很多种,它们各有各的特点,分别应用在不同的场合,而且可以嵌套使用。我们要根据我们的界面设计选择合适的布局,可能有些时候不同的布局可以达到同样的效果,但是“层次”越少的布局执行效率越高,因此,我们要选择最合适的布局来尽量减少界面的“层次”。下面,我们一个个来看看这些布局。

3.2.2线性布局(LinearLayout)

LinearLayout,也就是线性布局,是Android开发中最常用的布局之一。它以你为它设置的水平或垂直的属性值,来排列所有的子元素。包含在LinearLayout里面的控件按顺序排列成一行或者一列,类似于Swing里的FlowLayout和Silverlight里的StackPanel,所有的子元素都被堆放在其它元素之后。因此一个垂直列表的每一行只会有一个元素,而不管他们有多宽。而一个水平列表将会只有一个行高(高度为最高子元素的高度加上边框高度)。LinearLayout保持子元素之间的间隔以及互相对齐(相对一个元素的右对齐、中间对齐或者左对齐)。

android:orientation="vertical"//垂直布局

android:orientation="horizontal"//水平布局

 

如果是垂直排列,那么将是一个N行单列的结构,每一行只会有一个元素,而不论这个元素的宽度为多少;如果是水平排列,那么将是一个单行N列的结构。如果搭建两行两列的结构,通常的方式是先垂直排列两个元素,每一个元素里再包含一个LinearLayout进行水平排列。

下面,我们以一个简单的例子来加以说明。

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="textview1"/>

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="textview2"/>

    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="textview3"/>

</LinearLayout>

 

效果如图3-2所示。

技术分享

图3-2 LinearLayout垂直布局

 

接着我们将android:orientation="vertical"属性改为"horizontal"来看看效果,如图3-3所示。

  技术分享  

图3-3 LinearLayout水平布局

 

可以很明显的看到,我们将布局模式由“垂直布局”改为“水平布局”之后,控件由按行排列变成了按列来排列。

另外,LinearLayout还支持为单独的子元素指定weight。好处就是允许子元素可以填充屏幕上的剩余空间。这也避免了在一个大屏幕中,一串小对象挤成一堆的情况,而是允许他们放大填充空白。子元素指定一个weight值,剩余的空间就会按这些子元素指定的weight比例分配给这些子元素。默认的weight值为0。还是用上面“水平布局”的例子,我们给第一个文本框添加上android:layout_weight="1"属性,效果如图3-4所示。

 技术分享

图3-4 LinearLayout中layout_weight的作用

 

可以看到,textview1将textview2和textview3文本框之外的空白都填充了。

 

经验分享:

在LinearLayout线性布局中,我们有的时候需要设置为水平居中/垂直居中,但是偶尔莫名其妙的设置对了但是却并不起效果,这个时候你就需要注意了,看它是垂直线性布局还是水平线性布局。

当垂直线性布局时,则水平居中有效;当水平线性布局时,则垂直居中有效。

如果这些都没有问题,则看看是不是高度或宽度设置有问题。

如果此时为垂直线性布局,你想设置为水平居中, android:width的属性设置为fill_parent则没有效果,设置为wrap_content则有效,另外,通过设置android:gravity="center_horizontal"也可以实现这样的效果,但需要注意的是,此时的android:width的属性需设置为fill_parent。垂直居中亦然。

 

3.2.3相对布局(RelativeLayout)

RelativeLayout,即相对布局是一种比较灵活的布局。首先RelativeLayout是一个容器,它里边的元素的位置是按照相对位置来计算的。RelativeLayout允许子元素指定他们相对于其它元素或父元素的位置(通过ID指定)。因此,你可以以右对齐、以左对齐,或上下,或置于屏幕中央的形式来排列两个元素。元素按顺序排列,因此如果第一个元素在屏幕的中央,那么相对于这个元素的其它元素将以屏幕中央的相对位置来排列。可能这样说还不是很好理解,我们也以一个例子来加以说明。

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

    xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="match_parent"

    android:layout_height="match_parent">

    <TextView

        android:id="@+id/name_text"

        android:layout_centerHorizontal="true"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="用户名"/>

    <EditText

        android:id="@+id/name_edit"

        android:layout_width="120dp"

        android:layout_height="wrap_content"

        android:layout_alignTop="@id/name_text"

        android:layout_toRightOf="@id/name_text"/>

    <TextView

        android:id="@+id/pwd_text"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="密码"

        android:layout_below="@id/name_text"

        android:layout_alignLeft="@id/name_text"

        android:layout_marginTop="50dp"/>

    <EditText

        android:id="@+id/pwd_edit"

        android:layout_width="120dp"

        android:layout_height="wrap_content"

        android:password="true"

        android:layout_alignTop="@id/pwd_text"

        android:layout_alignLeft="@id/name_edit"/>

</RelativeLayout>

在上面的布局文件中,我们让第一个元素name_text相对于父元素“水平居中”:android:layout_centerHorizontal="true";

接着让name_edit位于name_text的右边:android:layout_toRightOf="@id/name_text";

并与name_text的顶部对齐:android:layout_alignTop="@id/name_text";

然后让pwd_text位于name_text的下方:android:layout_below="@id/name_text";

为了更好的看到效果,我们再让它向下位移50dp:android:layout_marginTop="50dp";

并让它与name_text左对齐:android:layout_alignLeft="@id/name_text";

最后是pwd_edit,我们让它与pwd_text的顶部对齐:android:layout_alignTop="@id/pwd_text";

并与name_edit左对齐:android:layout_alignLeft="@id/name_edit"。

下面来看看具体的效果图,如图3-5所示。

技术分享

图3-5RelativeLayout相对布局

 

经验分享:

出于性能上的考虑,对于相对布局的精确位置的计算只会执行一次。也就是说,如果使用XML来指定这个layout,在你定义它之前,被关联的元素必须定义。而且如果在这个RelativeLayout中有元素a和元素b,要定义元素a在元素b的右边,元素b则需要先被定义。

 

另外,RelativeLayout中有很多不同于其他布局的属性,也正是由于这些属性使得RelativeLayout具有很强的灵活性,我们应该熟练地掌握它们。

    表3-1详细说明了相对于给定ID的控件的一些属性。

属性

说明

android:layout_above

将该控件的底部置于给定ID的控件之上

android:layout_below

将该控件的底部置于给定ID的控件之下

android:layout_toLeftOf

将该控件的右边缘与给定ID的控件左边缘对齐

android:layout_toRightOf

将该控件的左边缘与给定ID的控件右边缘对齐

android:layout_alignBaseline

将该控件的baseline与给定ID的baseline对齐

android:layout_alignTop

将该控件的顶部边缘与给定ID的顶部边缘对齐

android:layout_alignBottom

将该控件的底部边缘与给定ID的底部边缘对齐

android:layout_alignLeft

将该控件的左边缘与给定ID的左边缘对齐

android:layout_alignRight

将该控件的右边缘与给定ID的右边缘对齐

表3-1 相对于给定ID的控件的属性

 

表3-2详细说明了相对于父组件的一些属性。

属性

说明

android:layout_alignParentTop

如果为true,将该控件的顶部与其父控件的顶部对齐

android:layout_alignParentBottom

如果为true,将该控件的底部与其父控件的底部对齐

android:layout_alignParentLeft

如果为true,将该控件的左部与其父控件的左部对齐

android:layout_alignParentRight

如果为true,将该控件的右部与其父控件的右部对齐

android:layout_centerHorizontal

如果为true,将该控件的置于水平居中

android:layout_centerVertical

如果为true,将该控件的置于垂直居中

android:layout_centerInParent

如果为true,将该控件的置于父控件的中央

android:layout_marginTop

上偏移的值

android:layout_marginBottom

下偏移的值

android:layout_marginLeft

左偏移的值

android:layout_marginRight

右偏移的值

表3-2 相对于父组件的属性

第三章 界面UI的基石—UI布局(2)