将用户界面转化成XML布局
你刚刚完成的“Hello,World”的例子使用了我们称作”programmatic”的UI布局。这意味着你直接使用代码来构造和创建应用程序用户界面。如果你完成大量的用户界面编程,你可能会意识到这种方法有时是多么的脆弱:一个版面小小的改动导致大量的源码问题.同时也非常容易忘记连接适当的视图,这都会导致你的版面错误,并且浪费大量的时间来调试代码。
这就是为什么Android提供一个动态的UI 构造模型:基于XML的布局文件。最简单的阐明这个概念的方法就是举一个例子。下面是一个XML布局文件,在行为上它和上面你刚刚完成的使用程序构建的例子完全相同。
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="Hello, Android"/>
普通结构的Android XML布局文件是简单的.它是一个标记树、每一个标记都是一个试图类.在这个例子中,他是一个非常简单的树,只有一个元素TextView。你可以在你的布局文件中使用任何试图派生类的名字作为你的标记名,包括在你自己代码中定义的视图类。这种结构使得创建许多用户界面变得非常简单,只需要使用一个简单的结构和语法,相比较使用代码实现要容易得多。这个模型是从web开发模型中得到的灵感,在web开发中,你可以从你的应用程序逻辑中分离用户界面,然后再组合起来并填充数据。(This model is inspired by the web development model, where you can separate the presentation of your application (its UI) from the application logic used to fetch and fill in data.这句话不是很明白,所以翻译很牵强)
In this example, there are also four XML attributes. Here's a summary of what they mean:
这个例子中,有四个XML属性。下面是它们含义的概述:
属性 | 含义 |
xmlns:android | 这是一个XML命名空间定义,告诉Android工具你将要引用Android命名空间中定义的通用属性。在每一个Android布局文件中最外面的标记都有这个属性 |
android:layout_width | 这个属性定义了这个视图使用的最大屏幕宽度。在这个例子中,我们只有这一个视图,所以我们可以让它占有整个屏幕,这就使”fill_parent”值得含义。 |
android:layout_height | 这个和android:layout_width属性差不多,只不过这个定义的是屏幕可使用的高度。 |
android:text | 这个设置了TextView包含的文本。在这个例子中,就是我们使用的”Hello,Android”消息。 |
因此,这就使XML布局看起来的样子,但是它们放在什么地方呢?就在你的工程的res/路径下。”res”是”resources”的简写,它包含你的项目需要的所有非代码资源,包括图像,本地化字符串和XML布局文件。
Eclipse插件为你创建这些XML文件.在我们上面的例子中,我们简单地显示了一下。在包浏览器中,展开res/layout文件夹,编辑main.xml文件.用上面的文本替换并且保存修改。
现在打开包浏览器中源代码文件夹中的名为R.java的文件,你将看到如下的代码。
public final class R {
public static final class attr {
};
public static final class drawable {
public static final int icon=0x 7f 020000;
};
public static final class layout {
public static final int main=0x 7f 030000;
};
public static final class string {
public static final int app_name=0x 7f 040000;
};
};
一个工程的R.java文件定义了所有资源的索引。在你的代码中使用这个类作为你个比较快捷的方法去访问你的工程能够中的资源。对于像Eclipse这样子具有自动生成代码特性的IDE来说尤为功能强大,因为它可以让你快速和交互地定位你搜索的特定引用。
最重要的事情是注意到的事名为”layout”的内部类, 和它的成员域”main”。Eclipse插件会侦测到你添加了一个新的XML布局文件和重新生成的这个R.java文件,当你添加了新资源到你的项目中之后,你会发现R.java自动跟新。
最后要做的就是使用你的UI的新版本的XML文件修改你的HelloAndroid源码,以取代纯粹使用代码来修改。下面是你的新类看上去的样子,正如你所见,源码变得十分简单。
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(R.layout.main);
}
}
当你做这些修改时,不要只是拷贝和粘贴,试用以下R类的代码完成特性,你能发现它很有帮助。做完这些修改之后,回到前面重新运行你的应用程序-你需要做的所有事情就是点击那个绿色的Run 箭头图标,或者从菜单中选择 Run>Run Last Launched。你将看到…哦,正如你前面看到的一样,非常神奇!
最后,需要指出的是,这两种不同的布局产生的是完全一样的结果。
创建XML布局还有很多内容,不过这已经超出了我们这里讨论的范围。想了解这种强大的功能,请参考 实现一个用户界面 的文档。
调试你的工程
The Android Plugin for Eclipse also has excellent integration with the Eclipse debugger. To demonstrate this, let's introduce a bug into our code. Change your HelloAndroid source code to look like this:
Eclipse下Android插件提供了与Eclipse调试器的完美集成。为了演示这一点,让我们引入一个bug到代码中。如下所示修改你的HelloAndroid源代码。
public class HelloAndroid extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
Object o = null;
o.toString();
setContentView(R.layout.main);
}
}
这个修改引入了一个空指针异常到你的代码中。如果你重新运行你的应用程序,你将会看到如下界面:
为了找出导致错误的原因,在你的代码行”Object o=null;”设置一个断点(你只需要在Eclipse中双击这一行左边的空处。)然后从菜单中选择Run>Debug Last Launched 进入调试模式。你的应用程序将重启仿真器,但这次当它运行到你设置的断点时它会挂起。你就可以在Eclipse的调试节界面下一步一步进行跟踪,就像你在其它环境下作的一样。
如果你不使用Eclipse(如果你使用其它其它的IDE,或者间的的使用文本编辑工具和命令行工具),那么Eclipse插件就对你毫无帮助。不过你不用担心—你不会因为不使用Eclipse而损失什么。
Eclipse环境下的Android插件紧紧是一套Android SDK工具的一个封装而已(这些工具,象仿真器,aapt,adb,ddms和其它文档化的工具)因此,它也可以用其它工具来进行封装,比如说一个’Ant’创建文件。
Android SDK包括一个Python脚本,名字为”activityCreateor.py”,它可以用来为你的工程创建所有的源码和原始目录,也可以生成一个兼容Ant的build.xml文件。这可以让你从命令行创建你的工程,或者与你选择的IDE集成起来,例如,创建一个类似我们刚刚通过Eclipse创建的HelloAndroid工程,你可以使用这样的命令。
activityCreator.py --out HelloAndroid com.google.android.hello.HelloAndroid
为了创建这个工程,你要先运行命令’ant’,当这个命令成功执行,一个名为HelloAndroid.apk的文件将生成到文件夹bin/下面。这个.apk文件十一个Android包,它可以使用adb工具安装到你的仿真器中.想了解更多使用这些工具的信息,请阅读前面的引用文档。