2008年12月3日星期三

升级UI到XML布局

升级UI到XML布局

你刚完成的“Hello,World”例子使用叫作“programmatic”(编码)UI布局,也就是你直接在源代码中构造和建立你的应用程序UI。如果你做过UI编程,你可能了解道路有时可能非常不容易的:布局小变动可能导致代码方面的大头痛。忘记恰当地融入VIew也是非常容易的,这将导致布局错误,并浪费时间来调试你的代码。
这就是Android提供另外一种UI构造模式:XML布局文件的原因。解释这种模式的最容易的方法是展示一个例子。下面是一个XML布局文件,其行为等同于你刚完成的基于编码构造的例子:

android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Hello, Android"/>

一个AndroidXML布局文件的普通结构是简单的。它是一棵标记树,每个标记是View类的名称。这个例子是包含一个元素,TextView,的非常简单的树。你可以使用在XML布局文件中View扩展类的名称,包括你在自己代码中定义的自定义View类。这种结构使快速建立UI变得非常容易,相比你在代码中使用的结构和语法,更简单。这种模式对web开发模式更有吸引力,你能隔离应用程序的表示层(UI)和逻辑层(存取数据)。
这个例子中,有四个XML属性。下面总结他们的意思:
(1)xmlns:android
这是一个XML名称空间声明,告诉Android工具:你打算引用在Android名称空间定义的通用属性。在每个Android布局文件中的外层标签必须有这个属性。
(2)android:layout_width
这个属性定义了View使用的屏幕的有效宽度是多少。这个例子中,他是唯一的VIew,所以我们想它占用整个屏幕,“fill_parent”就是这个意思。
(3)android:layout_height
这个属性很像android:layout_width,只是用于规定有效高度。
(4)android:text
这个属性设置TextView应该包含的文本内容。在这个例子中,他是我们司空见惯的"Hello, Android" 信息。

所以,那就是XML布局文件看起来的样子,但是你把它放在哪里呢?放到你的项目下/res/layout目录下。“res”是资源单词的缩写,这个目录存放你的程序需要的非代码资源,包括图片、本地化字符、XML布局文件。
ADT插件为你创建一个XML文件。在我们的上面的例子中,我们简直从来没有使用它。在Package浏览器总,展开文件夹/res/layout,编辑文件main.xml,使用上面的文字提供main.xml的内容然后保存。
马上打开文件r.java,这个文件在Package浏览器的源代码文件夹中。你将会发现它现在看起来像这样:
public final class R {
public static final class attr {
};
public static final class drawable {
public static final int icon=0x7f020000;
};
public static final class layout {
public static final int main=0x7f030000;
};
public static final class string {
public static final int app_name=0x7f040000;
};
};

项目的R.java文件是一个指向文件中定义的所有资源的索引。你在你的源代码中使用这个类,作为一种快捷引用你项目中的资源的方式。这是特别强大的代码完成功能,该功能存在于诸如Eclipse的集成开发环境中,之所以强大是因为他让你快速地、互动地定位你正在寻找的具体引用。
现在要注意的重要事情是名叫“layout”的内嵌类,以及他的成员“main”。ADT插件注意到你增加了一个新的XML布局文件,然后产生了这个r.java文件。当你加入其他资源进入你的项目时,你会发现r.java会跟着改变。
你需要做的最后的事情是使用你的UI的新XML版本而不是硬编码版本来修改HelloAndroid源代码。下面是你的新类看起来的样子,正如你看到的一样,源代码变得非常简单:
package com.android.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}

当你做这个修改的时候,不要仅仅拷贝粘贴进入。在那个R类上试试代码完成功能。你可能会发现它会帮助你许多。
既然你已经做了修改,进一步重新运行你的程序,你需要做的所有事情是点击绿色的Run箭头图标,或者选择菜单Run > Run History > Hello, Android。你应该看到...好,和你以前看到的是完全相同的界面!毕竟,这一点是要表明,两种不同的布局方式产生了相同的结果。
创建XML布局文件有更多的知识,但是我们在这里只介绍这么多了。想要知道这种强力方式的更多信息请参见“Implementing a User Interface”。

调试你的工程项目

ADT插件也和Eclipse调试器进行了完美集成。为了证明这点,让我们介绍我们代码的一个BUG。像这样修改你的代码:
package com.android.hello;

import android.app.Activity;
import android.os.Bundle;

public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Object o = null;
o.toString();
setContentView(R.layout.main);
}
}

这个修改引入了一个NullPointerException异常。如果你再次运行你的程序,你最后会在模拟器上看到:


按"Force Quit"来终止应用程序,并关闭模拟器窗口。

为了找出更多的错误,在Object o = null;行上设置断点,设置断点的操作是双击紧靠源代码行的标记栏。从主菜单中选择菜单Run > Debug History > Hello, Android进入调试模式。你的应用程序会在模拟器中重新启动,但是这次她会挂起在你设置的断点处。你能在Eclipse调试视图中单步调试你的代码,正如你为其他任何程序做的事情一样。


没有Eclipse时创建工程项目

如果你没有使用Eclipse,比如如果你喜欢其他IDE,或者简单地使用文本编辑器和命令行工具,那么Eclipse插件不能帮助你。但是,不要太担心,你不会因为不使用Eclipse而损失任何功能。
Android插件实际只是对包含在AndroidSDK内的一套工具的封装,这套工具包括模拟器、AAPT、ADB、DDMS,以及其他在别的地方提到的工具。因此,使用诸如ant建立文件之类的别的工具封装这些工具是可能的。
AndroidSDK包含一个称为“activitycreator.py”的Python描述脚本,这个脚本用于为你的工程项目创建所有的源代码和目录桩,又兼容ant的build.xml。这允许你从命令行建立你的工程项目,或者和你选择的IDE集成。
例如,为了创建一个HelloAndroid项目,和你在Eclipse中创建的一样,你使用如下的命令:
activitycreator.py --out HelloAndroid com.android.hello.HelloAndroid

为了建立项目工程,你运行命令“ant”。当命令成功完成时,你会放置一个文件helloAndroid.apk到bin目录下。.apk文件是一个Android包,能使用adb工具在模拟器中安装和运行。
欲知更多信息,请阅读上面引用的文档。

没有评论: