一个安卓应用(Android app)的图形用户界面(graphical user interface)是由一系列有层级关系的View(视图组件)和ViewGroup(视图组件组)对象构成。View对象一般是像按钮(buttons)或者文字输入框(text fields)之类的图形界面部件(UI widgets),同时,ViewGroup对象是定义子视图对象如何布局的不可见容器(invisible view containers),比如一个网格(grid)或者一个纵向列表(vertical list)。
Android对于View和ViewGroup的子类提供一系列基于XML的命名和定义,因此,你可以用XML来定义你的用户界面。此类XML包含一系列有层级关系的UI元素(UI elements)。
图示1:展示ViewGroup是如何生成布局分支以及如何包含其他View对象
在这节课中,你将使用XML创建包含一个文字输入项和一个按钮的布局(layout)。然后,在下一节课,你将响应这个按钮的按下事件(button is pressed,译者注:就是按下按钮的事件),并且将文字输入项的内容发送到另外一个activity。
布局选择(Alternative Layouts)
有很多原因可以说明使用XML而不是在运行时代码中声明你的用户界面布局是非常重要的,但之中最重要的一点是你可以针对不同的屏幕大小创建不同的布局。例如,你可以创建两个版本的布局,然后告诉系统针对小屏幕使用其中之一,针对大屏幕使用另外一个布局。需更多信息,请参考“Supporting Different Devices”课程。
创建一个线性布局(Linear Layout)
打开“res/layout/”目录中的“fragment_main.xml”(译者注:最新的ADT会生成此文件,如果使用旧版本的ADT,打开activity_main.xml。建议升级更新你的ADT,否则以后会和文档对不上。)文件。
注意:在Eclipse中,当你打开一个布局文件,首先是在图形布局编辑器中打开。此编辑器帮助你以所见即所得的方式建造布局。在这节课中,你将直接面对XML。所以,点击位于屏幕底部的“fragment_main.xml”标签页,打开XML编辑器。
在创建此项目时选择的BlankActivity模板包含“fragment_main.xml”文件。此布局文件包含一个RelativeLayout根视图组件(root view)和一个TextView子视图组件(child view)。
第一步,删除“<TextView>”节点(element,译者注:这里是XML节点的意思,也翻译成XML元素。在英文文档中,布局文件中的视图组件都称为element,其中也有元件的意思。在译文中,如果不影响理解有时会省去element的翻译)并且替换“<RelativeLayout>”节点为“<LinearLayout>”。然后,添加“android:orientation”属性(attribute),并且设置为“horizontal”(水平的)。结果如下:
<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”的设置使子视图组件基于水平(horizontal)或者竖直(vertical)方向对齐分布。LinearLayout的每个子视图组件按照在XML文件中出现的顺序展现在屏幕上。
另外两个属性“android:layout_width”和“android:layout_height”是用来设置视图组件大小的,对于所有视图组件都是必须设置的。
因为LinearLayout是此布局的根视图组件,它应该设置宽度(width)和高度(height)为“match_parent”以充满此应用可用的整个屏幕区域。
如需更多关于布局属性的信息,请参阅Layout指南。
添加一个文字输入组件(Text Field)
要创建一个用户可编辑的文字输入项,需在“<LinearLayout>”内添加一个“<TextEdit>”节点。
像每个视图(View)对象一样,你必须通过定义某些XML属性(attributes)来指定“EditText”对象的特性(properties)。下面示例展示如何在“<LinearLayout>”节点(element)内部声明它:
<EditText android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
关于以上属性(attributes):
此属性指定该视图的唯一标识符。你可以使用此标识符在你的应用代码中引用该视图对象,比如,读取和控制(manipulate)这个对象(你将在下一课看到如何实现)。
当你从XML中引用任何资源对象(resource object)时,必须使用@符号。然后接资源类型(此例为“id”),一个斜线(slash,“/”),再然后是资源名称(“edit_message”)。
在资源类型之前的加号(“+”)仅当你第一次定义一个资源ID的时候需要。当你编译此应用,SDK工具将使用这个ID的名字在你的项目的“gen/R.java”文件中生成一个新的资源ID。这个新的资源ID可以用来用“EditText”元素。一旦这个资源ID按照此方法声明,其他对于此ID的引用就不需要加号了。加号只在指定一个新的资源ID的时候必须,同时,对于实体资源,比如,字符串和布局,是不需要加号的。对于资源对象更多的信息,参见下面的介绍。
关于资源对象(resource objects)
每个资源对象就是一个唯一整形数的名字,这个名字与一个应用的资源绑定,比如一个位图,布局文件或者字符串。
每个资源都有一个对应的资源对象定义在项目的“gen/R.java”文件中。你可以使用R这个类中的对象名字来引用你的资源,比如当你需要一个字符串来指定“android:hint”属性的时候。你也可以通过“android:id”属性来连接一个视图组件和一个指定的资源ID,此资源ID将可以用来在代码中引用这个视图组件。
每次编译,SDK工具都会自动生成“R.java”文件。你不应该编辑此文件。
需要更多信息,请阅读“Providing Resources”指南。
android:layout_width和android:layout_height
相对于使用确定的值设置宽度和高度,“wrap_content”值可以用来指定此视图组件只需按照内容需要调整大小。如果使用了“match_parent”值,这个“EditText”元素将填满屏幕,应为他将适应它的父件“LinearLayout”的大小。更多信息,参见Layouts指南。
此值是这个文字输入项为空时所显示的默认字符串。与其使用代码中写死的字符串,“@string/edit_message”引用一个在另外一个文件中定义的字符串资源。因为它引用一个实体资源(不仅仅是一个标识符),所以不需要加号。但是,由于你还没有定义此字符串资源,你将看到一个编译错误。你将在下一章节定义一个字符串以修复这个错误。
注意:此字符串资源使用了与这个节点的ID相同的名字:“edit_message”。但是,资源的引用总是以资源类型来决定作用域的(比如,“id”或“string”),所以使用了同样的名字并不会产生冲突。
添加字符串资源
当你需要在用户界面上添加文字时,应该总使用字符串资源。字符串资源允许你在一个地方管理所有的UI文字,这将使查找和更新文字更简单。外部定义字符串也可以通过提供不同的字符串资源使你可以对于不同语言本地化你的应用。
默认情况下,你的Android项目包含一个字符串资源文件“res/values/string.xml”。在此文件中添加一个名字为“edit_message”的字符串,并且设置值为“Enter a message.”(你可以删除“hello_world”字符串。)
在这个文件中,同时为一个即将用到的按钮添加一个“Send”字符串。名字使用“button_send”。
“string.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="action_settings">Settings</string>
<string name="title_activity_main">MainActivity</string>
</resources>
需要更多为其他语言本地化你的应用的信息,请参阅课程“Supporting Different Devices”。
添加一个按钮
现在,在“<EditText>”节点下面,紧接着在布局(layout)中添加一个“<button>”。
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send" />
高度和宽度设置为“wrap_content”,因为此按钮只需要适合按钮中文字的大小。此按钮不需要“android:id”属性,因为目前它不会被activity的代码所引用到。
设置输入框的宽度充满屏幕
目前,EditText和Button在当前设计的布局中大小仅为适合它们的内容,像图示2所显示的。
图示2:宽度设置为“wrap_content”的EditText和Button部件
对于按钮来说,这没问题,但是对于文字输入框,这并不好,因为用户可能输入较长的内容。所以,让文字输入框占据剩余的屏幕宽度会比较好。我们可以通过“LinearLayout”的“weight”(权重)属性(property)来实现。使用“android:layout_weight”属性来指定。
“weight”(权重)值是一个数字,该数字指定每个视图组件相对于与它同级别的其他视图组件所应该占据的剩余空间的量。这类似于在一个饮料配方中的原料量:“2份伏特加,1份咖啡甜酒”表示饮料中的2/3是伏特加。例如,如果你设置一个视图组件的权重为2,另外一个为1,总和为3,所以第一个视图组件占据2/3的剩余空间,第二个占据其余的。如果你再添加一个视图组件,并且设置权重为1,这时,第一个视图组件(权重为2的)将获得1/2的剩余空间,另外的两个各得1/4。
所有视图组件的缺省权重为“0“。所以如果给其中任意一个视图组件指定一个大于0的权重,这个视图组件将占据除去其他视图所需要的空间后剩余的所有空间。所以,要让EditText在布局中占据剩下的空间,只需要设置它的权重为1同时保留按钮为无权重。
<EditText
android:layout_weight="1"
... />
当你设置了权重,为了增强布局的效率,你应该更改“EditText”的宽度为0(0dp)。设置宽度为0将增强布局的性能,因为使用“wrap_content”作为宽度,要求系统计算一个此处完全没有用的宽度数值,因为设置的权重值将导致另外的计算来填充剩余的空间。
<EditText
android:layout_weight="1"
android:layout_width="0dp"
... />
图示3展示设置权重之后的“EditText”:
图示3:EditText由于设置了权重,占据了LinearLayout中的剩余的空间
下面为你的布局文件现在的样子:
<?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类,所以你现在可以通过运行你的应用看到结果:
通过Eclipse,点击工具栏上的“Run”。
或者通过命令行,切换到你的Android项目的根目录,然后运行:
ant debug adb install bin/MyFirstApp-debug.apk
继续下一课,你将学习到如何响应按按钮的事件,如何从字符输入框中读取内容,如何启动另一个activity,等等。
此文章整体或部分翻译自Android Open Source Project的文档。依照Creative Commons 2.5 Attribution License使用并分享。此文章(译文,中文)原始链接为“[安卓教学] 创建你的第一个安卓应用 - 第三课 - 建立一个简单的用户界面”。原文(英文)链接为“Building a Simple User Interface”。
< 上一课 | 课程介绍 | 下一课 > |