第六章 安卓用户界面

这一章节,你将要学习怎样构建一个安卓用户界面,你将要创建自己的第一个活动,学习如何创建一个XML布局,以及怎样连接到java。您将了解视图(或小部件)和布局,以及学习如何处理这些事件,如按钮点击。此外,你可以向你的项目中添加一个类似Twitter的API作为一个外部支持的jar文件,所以你可以使应用程序调用云。

章节的末尾,你将要开始类似Twitter的安卓APP,该应用程序将采用一个单一的屏幕,将提醒用户当前的状态更新以及在线的更新。

创建用户界面的两种方式

创建安卓用户界面有两种方式,一个是陈述式的,一个是编程式的。他们是完全不同的,但通常是一起使用来完成工作

声明用户界面

声明的方法包括使用XML声明UI的形式,类似于使用HTML制作网页。标注标记并将指定的元素显示在屏幕上,如果你手编了一个HTML网页的程序,和创建安卓屏幕做几乎相同的工作。

该声明方法的一个好处是你可以用你所见即所得的工具。一部分工具来自于Eclipse安卓开发工具的扩展,其他三部分来自于第三方。此外,XML是相当有可读性的,对安卓平台和框架不熟悉的人可以很容易的确定用户界面的意图。

该声明方法的缺点是通过XML你能达到的就只有这么远。XML擅长用户界面的外观和感性,但它并不能提供一个处理用户输入的好方法。这是编程式方法是的所在。

编程用户界面

编程用户界面包括写jaa代码来 开发UI,如果你之前做过任何的java AMT开发或者java Swing开发,在这方面和安卓是相同的,和其他语言中的用户界面工具包类似。

基本上,如果你想创建一个按钮程序,你必须声明按钮变量,创建一个实例,将其添加到容器中,并设置有意义的任何按钮属性,如颜色、文本、文本大小、背景等。你或许 也想声明按钮的功能,你将要添加其他的代码,你将要写很多行的代码在结束之前。

你可以以声明的方式做任何事情,同样你也可以做 程序,但java 同时也让你详细的说明在被点击的时候按钮将实现什么功能。对用户界面来说这是编程方法的主要优点。

两全其美

所以使用哪种方法呢?最好的实践使用这两种,你会使用一个声明式的方法来声明所有的用户界面是静态的。例如屏幕的布局,控件等。当用户与用户界面发生交互时,你可以切换到一个编程的方法来定义,换句话说,你将要使用XML来声明按钮的外表以及用代码来说明其功能。

注意有两种方法来开发用户界面,但到了那一天结束时,所有的XML实际上是“膨胀”到内存空间好像是你真正写了代码,所以它是唯一运行的代码。

视图和布局

安卓组织用户界面元素到视图和布局。一些实物,例如例如一个按钮、标签和文本框都是一个视图。布局组织视图,如将一个按钮,一个标签和一组元素组合在一起, 如果你有java AMT或Swing的经验,布局类似于java容器视图,类似于java组件。安卓中的视图有时指代控件。

不要将安卓用户界面中的控件和应用程序控件混和,后者是可嵌入在其他应用程序中的小型应用程序视图。现在我们指的控件类似于活动中的视图。

所以一个布局包含其他子项,这些子项本身也可以是进一步的布局,从而形成一种复杂的用户界面结构,布局负责为每个子项分配空间。

下面列举一些常见的布局,虽然还有其他布局,但不常用。

线性布局

线性布局是最简单和常用的布局之一,它只是简单的横向或纵向的布局其子项,子项的顺序很重要,当布局询问其子项需要多少空间时,它会按顺序为每个子项分配它所需要的空间,所以如果一个先加入的子项占据了整个屏幕大小就不会为后续的子项分配更多空间。

线性布局的一个重要属性是layout_orientation,其有效的选项有垂直和水平,用以指示它是垂直排列还是水平排列。

虽然线 性布局是最简单和常用的布局,但他并不是最最好的选择,一个好的经验法则是,如果你开始嵌套多个线性布局你就开始使用不同的布局,例如relativelayout,过多的嵌套布局释放用户界面所需的时间越长,会浪费较多的CPU时间,也会使电池的续航受到影响。

表格布局

TableLayout在一个表格中对子项进行布局,它包含的视图是TableRow ,每个TableRow 都代表表中的一行,并可以包含其他UI控件,TableRow 水平方向上排列,这与水平排列的线性布局相似。对熟悉HTML的人来说,表格布局类似于

元素,而Table Row类似于元素,HTML还提供
、来代表表格中的每个单元格,Android根据你添加的视图动态决定列数。

表格布局的一个重要属性是stretch_columns,表明要展开表中的哪一列,同时你也可以使用*展开所有的列。

帧布局

FrameLayout将其子项互相叠放起来,以使最新子项覆盖前一个,像一副扑克牌那样。举例来说,这种布局策略可用于标签页。FrameLayoutye也可用于以后将用编程方式添加其他控件的一个预留位置

相对布局

RelativeLayout根据其子项彼此的相对位置来布局。这是非常强大的因为他不需要你嵌套格外的布局,就能实现复杂的布局。 RelativeLayout可以使需要绘制控件的总数减少,能提高应用程序的总体性能。另一方面,它要求每一个视图都有一个ID,以便可以相对于其他子项来定位它。

绝对布局

绝对布局布置其子项在屏幕的绝对坐标,对WYSIWYG来说是最好的布局,尽管简单但不灵活,你的用户界面在一个特别的屏幕上看起来还好,但不久屏幕大小、方向、分辨率改变。绝对布局不能调整。

启动Yamba项目

我们将启动Yamba项目。所以先启动Eclipse然后点击File→New→Android Project。

你会得到一个对话窗口,询问你新的安卓项目(如图6-2)的相关信息。下面再次解释所有的重要栏目。

项目名称

Eclipse据此名称组织我们的项目。出于方便以后使用命令行的考虑,最好不要在项目名称中包含空格。在这里输入Yamba。

内容

新建一个项目,明白意图。

树立目标

这个文件暗示了我们运行应用程序的安卓系统类型,可以是任何的安卓平台,标准的亦或专有的。我假设在安卓2.3上工作,就选择安卓2.3平台。

应用程序名称

类似于一个应用程序的纯文本名称,可以是任何的文本,对于我们的应用程序可以自由进出Yamba。

包名称

这是一个java类型的包,需要遵循包命名约定,简单的说,使用一个反响域名的包,在这里我将要使用“com.marakana.yamba”

创建活动

创建活动的选项是项目的一部分,你可以对它进行检查。对于活动名称,我们必须遵循java类命名约定。这样做意味着使用upper camelCase。在这里我要进入“statusactivity”。

最小的SDK版本

代表了Android SDK的最低版本必须安装在设备上运行他们的这个特定的应用,通常情况下,这个数字将对应于你选择的目标,在我们的情况下,安卓9。但是,如果应用程序不依赖于最新的和最伟大的应用程序接口或是能够缩放到较低的应用程序接口,你应该重新考虑这个数字。

在我们的情况下,应用程序将能够在应用程序接口水平4(安卓1.6),所以进入4。这是一个很好的选择,因为相对于安卓2.3,我们可以分化更多我们的应用程序方式。

点击完成。你的yamba项目现在应该出现在Eclipse的包资源管理器。

图6-2

活动状态布局

让我们设计我们的屏幕用户界面,在那里我们将进入新的状态,然后点击一个按钮来更新它。默认情况下,Eclipse在res/layout下建立一个名为main.xml的文件。为了保持一致,我们应该将此文件重命名为status.xml匹配我们的statusactivity。

在Eclipse重新命名一个文件,右击 ,选择Refactor→Rename…,然后进入一个新的命名空间,Eclipse重命名文件稍微有点灵活,不仅仅是名称的变化。它同时提供了文件的参考及更新。 尽管 在重命名java这个文件时这个特辑运行良好,它不是完全自动的XML文件。所以,重命名该文件要求我们在Java里通过R类换线。这样做,在活动状态的onCreate(),更换setContentView(R.layout.main); to setContentView(R.layout.status);

这个屏幕将包括四部分:

在屏幕上方建立一个标题,这将是一个TestView控件。

一个大的文本区域来键入我们的140个字符状态更新,我们将使用一个EditText控件来实现这个目的。

点击按钮来更新状态,这将建立一个Button控件。

一个布局包含所有的控件,将它们按照一个接一个的垂直的方式放置,对于这个屏幕我们将使用LinearLayout。

Example 6-1包含了我们活动状态布局的源代码。

Example 6-1. res/layout/status.xml <?xml version="1.0" encoding="utf-8"?>

此代码是由Eclipse图形布局产生的,如图6-3所示。Android开发工具(ADT)的Eclipse插件提供了帮助你的Android特定的XML文件的工作。 你也可以通过在窗口底部选择status.xml选项卡查看原始XML,这将为你提供这个屏幕的源代码,如这个例子所显示的。

尽管原始的章节中我们讨论过XML的基本意思,同时你也应该知道代码中的一些细节,我们将在下面的部分检查。

重要部件属性

你可能经常使用的属性是:

layout_height 和 layout_width

定义这个小部件的空间是由它的父布局来显示的,虽然你可以输入一个像素,英寸,或类似的值,那不是一个好的实践,因为它可以在各种不同的拥有不同型号屏幕的设备上运行,你想使用相对大小的组件,而不是绝对的。所以最好的实践将是使用fill_parent 或者 wrap_content ,fill_parent意味着你的控件所需要的所有可用空间都来自它的父类,wrap_content意味着它只需要尽可能多的空间,因为它需要

显示自己的内容。注意在API级别以及更高,fill_parent改名为match_parent。

layout_weight

layout_weight是从零到一的数字,这意味着我们的布局要求的重量,

例如,如果我们的Status EditText有一个0的默认布局,以及需要一个fill_parent的layout height。