Understanding User Interface in Android - Part 1: Layouts(译)

    无意中看到的几篇文章,想翻译出来分享给大家。不过声明,翻译后的意思不一定能完全表达作者的意图,如果想看原文,请参考:

    http://mobiforge.com/designing/story/understanding-user-interface-android-part-1-layouts

     

     

    到目前为止,我之前的几篇关于Android的文章都集中于向你展示如何解决Android中的问题,而没有花太多的时间来讨论Android应用程序开发的视觉元素——UI设计。在这篇和接下来的文章,我将带你穿越构建Android应用程序的UI元素。文章的开始部分,我将讨论Android中的一些布局(Layouts)和一些在屏幕上摆放的构件(Widget)。

     

    Android屏幕UI组件

     

    到这个时点,你已经看到Android应用程序最基本的单元式ActivityActivity用于显示应用程序的UI,它可能包含许多构件,如buttons, labels, text boxes等。一般,你会使用一个XML文件(例如,位于res/layout文件夹下的main.xml文件)来定义你的UI,它看起来像这样:

     

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       
    android:orientation="vertical"
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    >
        <TextView 
           
    android:layout_width="fill_parent"
           
    android:layout_height="wrap_content"
           
    android:text="@string/hello"
           
    />
    </LinearLayout>

     

    在运行时,你在ActivityonCreate事件处理函数里加载XML UI,使用Activity类的setContentView方法:

     

        @Override
        public void onCreate(Bundle savedInstanceState) {            
                super.onCreate(savedInstanceState);            
                setContentView(R.layout.main);
        }

     

    在编译期间,XML文件中的元素会编译成相应地Android GUI类,并设定了指定的特性。当加载时,Android系统会创建ActivityUI

     

    使用XML文件来构建UI往往是比较容易的,然后,也存在一些时候需要你在运行时动态地构建UI(例如,当编写游戏)。因此,也有可能完全通过代码来创建的你的UI

     

    Views和ViewGroups

     

    一个Activity包含ViewViewGroup。一个View是一个构件,它在屏幕上有一个外观。构件包括buttons, labels, text boxes等。一个View继承自android.view.View基类。

     

    一个或多个View可以组合起来放入一个ViewGroup。一个ViewGroup(它是特殊类型的View)提供一个布局,在其上你可以安排View的显示和次序。ViewGroup包括LinearLayout, FrameLayout等。一个ViewGroup继承自android.view.ViewGroup基类。

     

    Android支持以下的ViewGroup

     

    • LinearLayout
    • AbsoluteLayout
    • TableLayout
    • RelativeLayout
    • FrameLayout
    • ScrollView

     

    接下来的章节将讨论每个ViewGroup的细节。注意,在练习中,通常会嵌套不同类型的布局来创建想要的UI

     

    创建一个简单工程

     

    创建一个新的Android工程,如图1所示命名它。

     

    1  使用Eclipse来创建一个新的Android工程

     

    Eclipse支持很少的Android UI设计,因此,你不能在设计面板上进行构件的拖拽。作为替代的,你可以使用免费的DroidDraw工具(从 http://www.droiddraw.org/ 获取)。图2显示了动作中的DroidDraw。你可以在不同的布局上拖拽构件,然后使用它来生成等价的XML代码。然后DroidDraw不是很完美,对于你刚开始AndroidUI设计来说还是非常有用的,并且它是学习Android中众多的ViewViewGroup的得力工具。

     

    2  DroidDraw网页应用程序来设计你的AndroidUI

     

    你还可以下载独立的DroidDraw版本(Windows, Mac OS X, Linux)。

     

    LinearLayout

     

    LinearLayout以单一的行或列来布局View。子View既可以垂直摆放也可以水平摆放。查看LinearLayout如何工作,让我们修改一下工程的main.xml文件:

     

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       
    android:orientation="vertical"
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    >
        <TextView 
           
    android:layout_width="fill_parent"
           
    android:layout_height="wrap_content"
           
    android:text="@string/hello"
           
    />
    </LinearLayout>

     

    main.xml文件中,可以看到根元素是<LinearLayout>,并且它包含一个<TextView>元素。<LinearLayout>元素控制着其内元素的顺序和显示。

     

    每个ViewViewGroup都有一堆通用的特性,其中一部分显示在表1中。

     

    特性

    描述

    layout_width

    指定ViewViewGroup的宽度

    layout_height

    指定ViewViewGroup的高度

    layout_marginTop

    指定ViewViewGroup上方的空间

    layout_marginBottom

     指定ViewViewGroup下方的空间

    layout_marginLeft

    指定ViewViewGroup左边的空间

    layout_marginRight

    指定ViewViewGroup右边的空间

    layout_gravity

    指定子View 如何摆放

    layout_weight

    指定Layout的剩余空间的多少分配给View

    layout_x

    指定ViewViewGroupx坐标

    layout_y

    指定ViewViewGroupy坐标

    1  ViewViewGroup的通用特性

     

    注意,这些特性中的部分只在当一个View位于某个特定的ViewGroup里才能应用。例如,layout_weight和layout_gravity特性只能当View位于LinearLayout或者TableLayout里才能应用。

     

    举个例子,上面的<TextView>元素使用fill_parent常量填充了父元素的全部宽度(在这里是屏幕)。它的高度使用wrap_content常量,表示它的高度依据内容的高度(在这里,是其内的文本)。如果确实不想让<TextView>View占据整个行,那么,你也可以设定layout_width特性为wrap_content,像这样:

     

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello"
        />

     

    这样设置意味著View的宽度与其内包含的文本的宽度一样,你还可以设置宽度为一个绝对的值,像这样:

     

    <TextView
        android:layout_width="105px"
        android:layout_height="wrap_content"
        android:text="@string/hello"
        />

     

    在这里,宽度设置为105像素宽。让我们修改main.xml文件,添加一个<Button>View吧,如下所示:

     

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >
        <TextView
           
    android:layout_width="105px"
           
    android:layout_height="wrap_content"
           
    android:text="@string/hello"
           
    />
        <Button
           
    android:layout_width="100px"
           
    android:layout_height="wrap_content"
           
    android:text="Button"
           
    />
    </LinearLayout>

     

    3显示了View从左往右摆放。

     

     

    3  LinearLayoutView的摆放

     

    LinearLayout默认的方向为水平的。如果你想修改它的方向为垂直的,设置orientation特性为vertical,像这样:

     

    <LinearLayout
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    android:orientation="vertical"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >

     

    4显示了修改方向为垂直方向的效果。

     

     

    4  修改方向为垂直方向

     

    LinearLayout中,你可以应用其内View的layout_weight和layout_gravity特性,如下面对main.xml的修改所示:

     

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    android:orientation="vertical"
       
    >
        <TextView
           
    android:layout_width="105px"
           
    android:layout_height="wrap_content"
           
    android:text="@string/hello"
           
    />
        <Button
           
    android:layout_width="100px"
           
    android:layout_height="wrap_content"
           
    android:text="Button"
           
    android:layout_gravity="right"
           
    android:layout_weight="0.2"
           
    />
        <EditText      
           
    android:layout_width="fill_parent"
           
    android:layout_height="wrap_content"       
           
    android:textSize="18sp"
           
    android:layout_weight="0.8"       
           
    />
    </LinearLayout>

     

    5显示了Button通过使用layout_gravity特性将其摆放在父元素(LinearLayout)的右侧。如此同时,使用layout_weight特性,ButtonEditText以一定的比率占据屏幕剩余的空间。layout_weight特性值的总和必须等于1

     

     

    5  应用layout_weight和layout_gravity特性

     

    AbsoluteLayout

     

    AbsoluteLayout允许你指定孩子的精确位置。假设main.xml中定义了下面的UI

     

    <?xml version="1.0" encoding="utf-8"?>
    <AbsoluteLayout
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >
        <Button
           
    android:layout_width="188px"
           
    android:layout_height="wrap_content"
           
    android:text="Button"
           
    android:layout_x="126px"
           
    android:layout_y="361px"
           
    />
        <Button
           
    android:layout_width="113px"
           
    android:layout_height="wrap_content"
           
    android:text="Button"
           
    android:layout_x="12px"
           
    android:layout_y="361px"
           
    />
    </AbsoluteLayout>

     

    6显示了两个Button,使用android:layout_x和android:layout_y特性来定位它们指定的位置。

     

     

    6  AbsoluteLayout中摆放View

     

    作者的提醒:当屏幕的旋转发生改变,你需要重新摆放你的View时,你最好使用AbsoluteLayout

     

    TableLayout

     

    TableLayout以行列的方式来组合View。你可以使用<TableRow>元素来在表中生成一行。每一行可以包含一个或多个View。你在行中放置的每个View会形成一个单元。每列的宽度由这一列中单元的最大宽度来决定。

     

    以下面的元素来填充mail.xml,观察UI如图7所示:

     

    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    android:layout_height="fill_parent"
       
    android:layout_width="fill_parent"
       
    android:background="#000044">
        <TableRow>
            <TextView
               
    android:text="User Name:"
                android:width =
    "120px"
               
    />
            <EditText
               
    android:id="@+id/txtUserName"
               
    android:width="200px" />
        </TableRow>
        <TableRow>
            <TextView
               
    android:text="Password:"
               
    />
            <EditText
               
    android:id="@+id/txtPassword"
               
    android:password="true"
               
    />
        </TableRow>
        <TableRow>
            <TextView />
            <CheckBox android:id="@+id/chkRememberPassword"
               
    android:layout_width="fill_parent"
               
    android:layout_height="wrap_content"
               
    android:text="Remember Password"
               
    />  
        </TableRow>
        <TableRow>
            <Button
               
    android:id="@+id/buttonSignIn"
               
    android:text="Log In" />
        </TableRow>
    </TableLayout>

     

    图 7  使用TableLayout

     

    注意,在上面的例子中,TableLayout中有两列四行。Password正下方的TextView填入了一个空的元素。如果你不这么做,记住密码的Checkbox将会出现在Password TextView的下方,如图8所示。

     

    8  注意记住密码Checbox位置的改变

     

    RelativeLayout

     

    RelativeLayout允许你指定子View的位置相对于其它的View。假设main.xml文件如下面所示:

     

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout
       
    android:id="@+id/RLayout"
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >
        <TextView
           
    android:id="@+id/lblComments"
           
    android:layout_width="wrap_content"
           
    android:layout_height="wrap_content"
           
    android:text="Comments"
           
    android:layout_alignParentTop="true"
           
    android:layout_alignParentLeft="true"
           
    />
        <EditText
           
    android:id="@+id/txtComments"
           
    android:layout_width="fill_parent"
           
    android:layout_height="170px"
           
    android:textSize="18sp"
           
    android:layout_alignLeft="@+id/lblComments"
           
    android:layout_below="@+id/lblComments"
           
    android:layout_centerHorizontal="true"
           
    />
        <Button
           
    android:id="@+id/btnSave"
           
    android:layout_width="125px"
           
    android:layout_height="wrap_content"
           
    android:text="Save"
           
    android:layout_below="@+id/txtComments"
           
    android:layout_alignRight="@+id/txtComments"
           
    />
        <Button
           
    android:id="@+id/btnCancel"
           
    android:layout_width="124px"
           
    android:layout_height="wrap_content"
           
    android:text="Cancel"
           
    android:layout_below="@+id/txtComments"
           
    android:layout_alignLeft="@+id/txtComments"
           
    />
    </RelativeLayout>

     

    注意,放入RelativeLayout中的View都有特性来设置它们与其它View对齐。这些特性是:

     

    • layout_alignParentTop
    • layout_alignParentLeft
    • layout_alignLeft
    • layout_alignRight
    • layout_below
    • layout_centerHorizontal

     

    这些特性的值是你已经为View定义的ID。上面的XML UI创建的屏幕如图9所示。

     

     

    9  使用AbsoluteLayout来摆放View

     

    FrameLayout

     

    FrameLayout是屏幕上的一个占位符,你可以用它来显示单个View。添加到FrameLayout上的View总是位于布局的左上角。假设main.xml中有以下内容:

     

    <?xml version="1.0" encoding="utf-8"?>
    <AbsoluteLayout
       
    android:id="@+id/widget68"
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >
       
    <FrameLayout
           
    android:layout_width="wrap_content"
           
    android:layout_height="wrap_content"
           
    android:layout_x="40px"
           
    android:layout_y="35px"
           
    >       
           
    <ImageView
                android:src =
    "@drawable/androidlogo"
               
    android:layout_width="wrap_content"
               
    android:layout_height="wrap_content"
               
    />
       
    </FrameLayout>
    </AbsoluteLayout>
    </p>
     
    <p>Here, you have a <code>FrameLayout

     

    AbsoluteLayout中,放置了一个FrameLayout,其中嵌入了一个ImageViewUI如图10所示。

     

    注意:这个例子假设res/drawable文件夹下有一个名叫androidlogo.png图片。

     

     

    10  使用FrameLayout

     

    如果你添加另一个View(例如一个Button)到FrameLayout上,新的View将遮盖前一个View(如图11所示):

     

    <?xml version="1.0" encoding="utf-8"?>
    <AbsoluteLayout
       
    android:id="@+id/widget68"
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >
        <FrameLayout
           
    android:layout_width="wrap_content"
           
    android:layout_height="wrap_content"
           
    android:layout_x="40px"
           
    android:layout_y="35px"
           
    >       
            <ImageView
                android:src =
    "@drawable/androidlogo"
               
    android:layout_width="wrap_content"
               
    android:layout_height="wrap_content"
               
    />           
            <Button
               
    android:layout_width="124px"
               
    android:layout_height="wrap_content"
               
    android:text="Print Picture"      
               
    />
        </FrameLayout>
    </AbsoluteLayout>

     

    11  重叠View

     

    你可以添加多个View到一个FrameLayout上,但每一个都将停靠在前一个的上方。

     

    ScrollView

     

    ScrollView是一种特殊类型的FrameLayout,它允许用户滚动查看View列表,而这些View将占据比实际显示更多的空间。ScrollView仅能容纳一个子ViewViewGroup,一般都是LinearLayout

     

    注意:不要将ListViewScrollView一起使用。ListView设计用来显示有联系的信息列表,并且为大列表的处理作了优化。

     

    接下来的main.xml的内容包含一个ScrollView,其中包含一个LinearLayoutLinearLayout中依次包含一些ButtonEditText

     

    <?xml version="1.0" encoding="utf-8"?>
    <ScrollView
       
    android:id="@+id/widget54"
       
    android:layout_width="fill_parent"
       
    android:layout_height="fill_parent"
       
    xmlns:android="http://schemas.android.com/apk/res/android"
       
    >
        <LinearLayout
           
    android:layout_width="310px"
           
    android:layout_height="wrap_content"
           
    android:orientation="vertical"
           
    >
            <Button
               
    android:id="@+id/button1"
               
    android:layout_width="fill_parent"
               
    android:layout_height="wrap_content"
               
    android:text="Button 1"
               
    />
            <Button
               
    android:id="@+id/button2"
               
    android:layout_width="fill_parent"
               
    android:layout_height="wrap_content"
               
    android:text="Button 2"
               
    />
            <Button
               
    android:id="@+id/button3"
               
    android:layout_width="fill_parent"
               
    android:layout_height="wrap_content"
               
    android:text="Button 3"
               
    />
            <EditText
               
    android:id="@+id/txt"
               
    android:layout_width="fill_parent"
               
    android:layout_height="300px"
               
    />
            <Button
               
    android:id="@+id/button4"
               
    android:layout_width="fill_parent"
               
    android:layout_height="wrap_content"
               
    android:text="Button 4"
               
    />
            <Button
               
    android:id="@+id/button5"
               
    android:layout_width="fill_parent"
               
    android:layout_height="wrap_content"
               
    android:text="Button 5"
               
    />
        </LinearLayout>
    </ScrollView>

     

    12ScrollView在屏幕的右侧显示了一个滚动条。用户可以往上拖拽屏幕来显示位于屏幕下方的View

     

    12  使用ScrollView

     

    小结

     

    在这一篇文章里,你已经看到了Android中用于创建UI的一些布局。下一篇文章中,我将向你展示一些ViewWidget),你可以使用它来创建杀手级的应用程序。至此,祝愉快!

posted on 2009-10-08 22:03  xirihanlin  阅读(1388)  评论(0编辑  收藏  举报