编写一个简单的安卓app界面

安卓的用户界面都是由View以及ViewGroup的子类对象组成的。View对象一般是想button或者textview这样的控件,ViewGroup对象是一个看不见的View容器,它定义了如何布局容器中装入的子View,比如是网格布局还是垂直布局等。

android提供了通过xml文件编写的方式来操作这些View和ViewGroup,所以尽管View和ViewGroup比较复杂,但是我们其实多数时候是在xml中操作他们的,难易程度就跟网页设计差不多。

本文将会指导你建立一个包含了文本编辑框和按钮的xml布局。后续的教程中,我们会为为按钮增加点击的响应事件。

创建一个LinearLayout

打开 res/layout/目录下的activity_main.xml文件。

注意:在eclispe下,默认打开一个xml文件显示的是xml文件的预览效果,而不是代码。本文是直接在xml代码里面操作,因此你需要点击一下底部的tab菜单中的 activity_main.xml,这样才可以编辑xml。

你创建的BlankActivity 工程模版其实是已经有了一个默认的布局的,但是他是相对布局,由RelativeLayout 包含一个文本显示框TextView 组成。
我们要将其改成线性布局。

首先删除TextView元素,同时将RelativeLayout替换成LinearLayout,然后增加android:orientation属性并设置成horizontal(水平)。

完成上面的步骤之后activity_main.xml应该是这样的:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >
</LinearLayout>

LinearLayout 是一个ViewGroup(即ViewGroup的子类),LinearLayout 中的子元素要么是单一的横向排列,要么是垂直排列,这取决于其android:orientation属性。子元素排列的先后顺序跟xml文件中出现的顺序是一致的。 android:layout_width 和 android:layout_height这两个属性是所有视图组件都需要的属性,缺少其中任何一个在运行代码的时候都会报错。这两个属性决定了该View的大小。

因为在activity_main.xml文件中LinearLayout是是最顶层的View,所以我们要将app界面充满整个屏幕的话应该将layout_width 和layout_height设置成"match_parent",顾名思义,match_parent就是充满父View的整个空间,而所有app的顶级View都是充满屏幕的。(新版本都是用match_parent,也可以用fill_parent来代替,但是官方不推荐这么写)。

关于 layout的其他属性,请参考谷歌官方文档。

添加一个文本编辑框

在xml中创建一个文本编辑框控件是用<EditText>标签,就跟其他的控件一样,你需要为它增加必要的属性设置。如下:

<EditText android:id="@+id/edit_message"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:hint="@string/edit_message" />

关于这些属性的解释:

android:id

id是一个view的唯一标识,通过id,你可以在代码中引用这些视图对象,读取或者修改他们。当我们在xml中引用资源文件的时候,必须要加上@符号。@符号紧跟着的是资源的类型(这里资源类型就是id)然后是"/"分隔符,最后是资源名称。所以`android:id=``"@+id/edit_message"`的意思就是引用一个名字叫`edit_messag`的id类型资源。

注意这里的id之前有一个+号。当我们第一次定义一个资源文件id的时候需要+,在编译app的时候,会在我们的 `gen/R.java`文件中生成一个资源文件id,id一旦被定义之后,其他队该id的引用都不再需要+号了。

android:layout_widthandroid:layout_height

与直接给这两个属性赋具体的值不同,`` `"wrap_content"` ``表示该view占据的空间大小取决于自身。如果值为`` `"match_parent"` ``,那么view的大小将充满其父容器。

android:hint

这个属性设置了文本输入框EditText在没有任何文字的时候显示给用户的默认值。`hint`属性的值在这里并没有直接给出,而是通过对资源文件string的引用来获得字符串。当我们的资源文件中还没有定义名叫`edit_message`的字符串的时候,直接编译是会报错的。下面我将会教你如何添加string资源文件。

添加字符串String资源文件

如果你想在用户界面中添加字符串,你应该将该字符串放在专门的资源文件中。这样做的好处是,当你需要修改UI中涉及到的字符串时,你只需修改一个文件就可以了,而不必在复杂的代码中寻找。而且,将字符串分离出来的好处是这样更容易实现对多语言的支持。默认情况下,你新建一个工程总是会产生res/values目录,目录下有strings.xml文件。打开该文件,添加一个name为“edit_message”,value值为"Enter a message."的字符串。因为我们稍后会在button上显示send一词,因此顺便我们再添加一个name为“button_send”,value值为"Send"的字符串。代码如下:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">My First App</string>
    <string name="edit_message">Enter a message</string>
    <string name="button_send">Send</string>
    <string name="action_settings">Settings</string>
    <string name="title_activity_main">MainActivity</string>
</resources>

至于对多种语言的支持方法,可以参考google官方其他文章。

添加一个按钮

上面我们在LinearLayout中添加了一个文本输入框EditText,紧接着我们通过如下代码在EditText的后面添加一个按钮:

<Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="@string/button_send" />

由于在activity中并没有引用button的地方,所以我们这里没有添加id属性。layout_width 和layout_height属性设置成wrap_content意味着按钮的大小取决于自身的内容。

将文本编辑框的宽度设置成适合屏幕的宽度

到现在为止,EditText 和``Button的大小都是wrap_content,也就是自身有多大,就显示多大。如图

这种设置对于button来说很合适,但是并不适合editText控件,因为editText是用来输入文字的,editText的自身内容是可变的,wrap_content只能保证其大小适应了最初该有的大小,当输入文字更长的时候,editText就满足不了了,所以最好还是设置成最大限度的充满屏幕的效果(除button外的剩余部分)。在LinearLayout中,我们可以通过_weight_权重来做到,也就是 `android:layout_weight属性。`

````` `` `android:layout_weigh` ``t就是决定如何分配剩余空间。举个例子,如果你给一个view的`` `layout_weight` ``设为2,另外一个View的```` ```的`` `layout_weight` ``设为1,那么剩余的空间就被划分成了三分,第一个View占两份,也就是2/3.``` ```` `````

```````默认所有View的```` ``` `` `layout_weight` `` ``` ````都为0,因此如果你只给某个View设置了```` ``` `` `layout_weight` `` ``` ````大于0的值,那么他将得到所有视图在分配完空间之后的全部剩余空间。所以这里我将``` `` `EditText` `` ```的`````` ````` ```` ``` `` `layout_weight` `` ``` ```` ````` ``````设为1,而按钮保持默认的状态。```````

<EditText
    android:layout_weight="1"
    ... />

注意:虽然在这种情况下,一般我们是将editText的宽度设为0,

android:layout_width="0dp"

为什么要这么做呢?其实是效率方面的考虑,如果使用"wrap_content",系统会先计算editText所需的空间,然后得出editText和button占据后还剩余多少空间,如果还有剩余,则将剩余宽度补给editText。如果我设置为0,editText部分的空间就不需要计算了。所以你应该这样写代码:

<EditText
    android:layout_weight="1"
    android:layout_width="0dp"
    ... />

修改了之后那么将会是如下效果:

整个布局文件的代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal">
    <EditText android:id="@+id/edit_message"
        android:layout_weight="1"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:hint="@string/edit_message" />
    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/button_send" />
</LinearLayout>

运行代码就能看到效果了。