构建一个简单的用户界面(Building a Simple User Interface)(翻译)

构建一个简单的用户界面

Android APP的图形化用户界面是使用一个层次化结构的View和ViewGroup对象。View对象通常是UI组件,例如button和text field。ViewGroup对象是不可见的view对象容器,定义子view对象如何布局,例如一个网格或垂直列表。

Android提供一个XML词汇表对应View和ViewGroup的子类,这样你就可以在XML中使用一个层次化结构的UI元素定义你的UI。

构建一个简单的用户界面(Building a Simple User Interface)(翻译)
上图表明ViewGroup对象如何在布局中形成分支以及包含其他View对象

在这一课中,你将在XML文件中创建一个布局,包含一个文本域(TextField)和一个按钮(Button)。在下一课中,当按钮被按下时,你将响应它并将文本域中的内容发送到另一个Activity。

创建一个线性布局

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

注意:在Eclipse里面,当你打开一个布局文件,你首先看到的是一个图形化布局编辑器。这是一个帮助你使用WYSIWYG工具构建布局的编辑器。在这课里,你将直接在XML上工作,因此点击屏幕底部的activity_main.xml标签来打开XML编辑器。

你创建工程的时候选择的BlankActivity模板包含activity_main.xml文件,这个文件有一个RelativeLayout根视图和一个TextView子视图。

首先,删除TextView元素并改变RelativeLayout元素为LinearLayout。然后添加android:orientation属性并设置为“horizontal”。结果如下所示:

<?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的一个子类),按垂直或水平方向布局子视图,由android:orientation属性指定。LinearLayout的各个子元素按在XML中定义的顺序显示在屏幕上。

另外两个属性android:layout_width和android:layout_height也需要指定从而为所有的视图指定大小。

由于LinearLayout是这个App布局中的根视图,通过设置宽度和高度为match_parent,使得它应该可以填充整个屏幕区域(App可以获得的区域)。这个值表明这个视图应该扩展它的宽度或高度去匹配父视图的宽度或高度。

如果需要了解更多Layout属性的信息,请看Layout指导。

增加一个文本域

为了创建一个用户可以编辑的文本域,在<LinearLayout>增加一个<EditText>属性。

像每个视图对象,你必须定义一个XML属性来确定一个EditText对象的属性。下面是指导你在<EditText>元素中应该如何声明它。

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

 关于这些属性:

android:id:这给这个视图提供一个唯一的标识符,你能在App的代码中通过这个引用对象,例如读取和操作这个对象(你会在下一课看到这个)。当你引用XML文件的任何资源对象时你需要@符号,紧跟着是资源类型(这里是id),一个斜线(/),然后是资源名字(edit_message)。

资源类型前的加号(+)只在第一次定义资源ID时才需要。当你编译App时,SDK工具使用这个ID名字来在你工程的gen/R.java文件中创建引用这个EditText元素一个资源ID。一旦按照这种方式声明了资源ID,其他的对这个ID的引用就不需要加号了。只有当指定一个新的资源ID时才需要使用加号,但是对于具体的资源如字符串和布局不需要。查看边栏获取更多关于引用对象的信息。

android:layout_width,android:layout_height:不是为宽度和高度使用具体的大小,值"wrap_content"指定这个视图的大小只要能适应内容就可以。如果你使用“match_parent”代替,则EditText会填充满屏幕,因为它会匹配父视图的大小LinearLayout,需要更多的信息,请看Layout指导。

android:hint:这是当文本域为空的时候默认显示的字符串,作为使用硬编码的字符串作为值的替代方法,"@string/edit_message"值引用定义在另一个文件中字符串资源。因为这个引用一个具体的资源(不只是一个标识符),它不需要加号。然而,由于你还没有定义字符串资源。你将会先看到一个编译错误。你将会在下一部分通过定义这个字符串来修复这个错误。

注意:字符串资源有同样的名字作为元素ID:edit_message。然而,资源的引用通过资源类型作为作用域,例如id或string。因此使用相同的名字不会产生冲突。

增加字符串资源

当你需要再用户界面增加文本,你应该始终确定一个字符串作为资源。字符串资源允许你在一个单独的地方管理所有的UI文本,使你查找和更新文本更容易。外部化字符串同样允许你本地化你的APP,通过为每个字符串资源提供可选择的不同语言的定义。默认的,你的Android工程文件包含一个字符串资源文件在/res/values/strings.xml,增加一个新的字符串命名为“edit_message”,设置值为“Enter a message”(你可以删除“hello world”那个字符串了)

当你在这个文件里的时候,也为你马上就要添加的按钮增加一个“Send”字符串,命名为“button_send”。

strings.xml文件结果如下所示:

<?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="menu_settings">Settings</string>
    <string name="title_activity_main">MainActivity</string>
</resources>

 要获得更多的关于使用字符串资源为其他语言本地化你的app的信息,请参考Supporting Different Devices课程。

增加一个按钮

现在增加一个<Button>到布局文件中,紧跟着<EditText>元素。

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

 高和宽度都被设置为“wrap_content”,因此这个按钮的大小就会正好适应按钮的文本。这个按钮不需要android:id属性,因为它不会在Activity的代码中被引用。

使输入框匹配屏幕的宽度

当前的布局设计使得EditText和Button组件的大小都正好适应它们的内容,如下图所示:

构建一个简单的用户界面(Building a Simple User Interface)(翻译)
 这对于按钮来说能够很好的工作,但是对于文本框不是,因为用户可能输入一些更长的东西,使用文本框填满屏幕未使用的宽度部分会很好。在LinearLayout中你可以使用weight属性来做到这个,使用android:layout_weight属性来指定。
weight值是一个数字用于指定剩余的空间中每个组件可以占用的量,相对于兄弟视图(同层级视图)所占用的量。这个的工作机制有点像饮料的配方。“两部分的伏特加,一部分的咖啡香甜酒”意味着饮料的三分之二是伏特加。举个例子,如果你给一个视图的weight为2,给另一个视图的weight为1,它们的和为3,因此第一个视图会占用剩余空间的2/3,第二个会填充剩余的。如果你增加了第三个视图并给它的weight置为1,则第一个视图会占用剩余空间的1/2,剩余的两个每个占用1/4。

所有视图的weight默认值为0,如果你给唯一的一个视图的任意的比0大的weight值,则当所有视图都被分配了请求的空间之后,那个视图将会占据所有的剩余空间。因此,为了能够让EditText元素能顾占据你的布局中的所有剩余空间,将EditTex的weight值职位1,保留button的weight值会默认值。

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

 为了改进布局效率,你应该改变EditText的宽度值设为0(0dp)。设置宽度的大小为0,从而改变布局的性能,因为使用“wrap_contents”作为宽度需要系统来计算一个宽度,但是这个宽度最终是不适用的,因为weight的值会要求另一个宽度的计算来填充剩余空间。

<EditText
    android:layout_weight="1"
    android:layout_width="0dp"
    ... />
 下图显示了你将所有的weight值设置到EditText元素的效果:

构建一个简单的用户界面(Building a Simple User Interface)(翻译)

你完成之后完整的布局文件如下所示:

<?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>
 这个布局文件被你创建工程时SDK工具生成的默认Activity类所使用。因此你可以运行这个app来查看结果:
  • 在Eclipse里面,在工具栏中点击Run。
  • 在命令行里面,切换到你Android工程的根目录下,然后执行:
ant debug
adb install bin/MyFirstApp-debug.apk
 继续下一课程学习如何响应按钮的按下,从文本框读取内容,启动另一个Activity及其他。
 

相关推荐