如前所述,Eclipse已默认打开activity_quiz.xml布局文件,并在Android图形布局工具里显示了预览界面。虽然图形化布局工具非常好用,但为更好地理解布局的内部原理,我们还是先学习如何使用XML代码来定义布局。 在代码编辑区的底部选择标为activity_quiz.xml的标签页,从预览界面切换到XML代码界面。 当前,activity_quiz.xml文件定义了默认的activity布局。应用的默认布局经常改变,但其XML布局文件却总是与代码清单1-1文件相似。 代码清单1-1 默认的activity布局(activity_quiz.xml) 首先,我们注意到activity_quiz.xml文件不再包含指定版本声明与文件编码的如下代码: ADT21开发版本以后,Android布局文件已不再需要该行代码。不过,在很多情况下,可能还是会看到它。 应用activity的布局默认定义了两个组件(widget):RelativeLayout和TextView。 组件是组成用户界面的构造模块。组件可以显示文字或图像、与用户交互,甚至是布置屏幕上的其他组件。按钮、文本输入控件和选择框等都是组件。 Android SDK内置了多种组件,通过配置各种组件可获得所需的用户界面及行为。每一个组件是View类或其子类(如TextView或Button)的一个具体实例。 图1-8展示了代码清单1-1中定义的RelativeLayout和TextView是如何在屏幕上显示的。 图1-8 显示在屏幕上的默认组件 不过,图1-8所示的默认组件并不是我们需要的,QuizActivity的用户界面需要下列五个组件: 一个垂直LinearLayout组件; 一个TextView组件; 一个水平LinearLayout组件; 两个Button组件。 图1-9展示了以上组件是如何构成QuizActivity活动用户界面的。 图1-9 布置并显示在屏幕上的组件 下面我们在activity_quiz.xml文件中定义这些组件。 如代码清单1-2所示,修改activity_quiz.xml文件。注意,需删除的XML已打上删除线,需添加的XML以粗体显示。本书统一使用这样的版式约定。 代码清单1-2 在XML文件(activity_quiz.xml)中定义组件 参照代码清单直接输入代码,就算不理解这些代码也没关系,你会在后续的学习中弄明白的。需要特别注意的是,开发工具无法校验布局XML内容,请避免输入或拼写错误。 根据所使用的工具版本不同,可能会得到三行以android:text开头的代码有误。先暂时忽略它们,以后再去解决这一问题。 将XML文件与图1-9所示的用户界面进行对照,可以看出组件与XML元素一一对应。元素的名称就是组件的类型。 各元素均有一组XML属性。属性可以看作是如何配置组件的指令。 以层次等级视角来研究布局,有助于我们更方便地理解元素与属性的运作方式。 1.4.1 视图层级结构 组件包含在视图对象的层级结构,即视图层级结构(view hierarchy)中。图1-10展示了代码清单1-2所示XML布局对应的视图层级结构。 图1-10 布局中组件及属性的层级结构 从布局的视图层级结构可以看到,其根元素是一个LinearLayout组件。作为根元素,Linear- Layout组件必须指定Android XML资源文件的命名空间属性为http://schemas.android.com/apk/ res/android。 LinearLayout组件继承自View子类的ViewGroup组件。ViewGroup组件是一个包含并配置其他组件的特殊组件。如需以一列或一排的样式布置组件,使用LinearLayout组件就可以了。其他ViewGroup子类还包括FrameLayout、TableLayout和RelativeLayout。 若某个组件包含在一个ViewGroup中,该组件与ViewGroup即构成父子关系。根LinearLayout有两个子组件:TextView和LinearLayout。作为子组件的LinearLayout本身还有两个Button子组件。 1.4.2 组件属性 下面我们一起来看看配置组件的一些常用属性。 1. android:layout_width和android:layout_height属性 几乎每类组件都需要android:layout_width和android:layout_height属性。它们通常被设置为以下两种属性值之一。 match_parent:视图与其父视图大小相同。 wrap_content:视图将根据其内容自动调整大小。 (以前还有一个fill_parent属性值,等同于match_parent,目前已废弃不用。) 根LinearLayout组件的高度与宽度属性值均为match_parent。LinearLayout虽然是根元素,但它也有父视图(View)——Android提供该父视图来容纳应用的整个视图层级结构。 其他包含在界面布局中的组件,其高度与宽度属性值均被设置为wrap_content。请参照图1-9理解该属性值定义尺寸大小的作用。 TextView组件比其包含的文字内容区域稍大一些,这主要是android:padding="24dp"属性的作用。该属性告诉组件在决定大小时,除内容本身外,还需增加额外指定量的空间。这样屏幕上显示的问题与按钮之间便会留有一定的空间,使整体显得更为美观。(不理解dp的意思?dp即density-independent pixel,指与设备无关的像素,第8章将介绍有关它的概念。) 2. android:orientation属性 android:orientation属性是两个LinearLayout组件都具有的属性,决定了二者的子组件是水平放置的还是垂直放置的。根LinearLayout是垂直的,子LinearLayout是水平的。 LinearLayout子组件的定义顺序决定着其在屏幕上显示的顺序。在竖直的LinearLayout中,第一个定义的子组件出现在屏幕的最上端。而在水平的LinearLayout中,第一个定义的子组件出现在屏幕的最左端。(如果设备语言为从右至左显示,如Arabic或者Hebrew,第一个定义的子组件则出现在屏幕的最右端。) 3. android:text属性 TextView与Button组件具有android:text属性。该属性指定组件显示的文字内容。 请注意,android:text属性值不是字符串字面值,而是对字符串资源(string resources)的引用。 字符串资源包含在一个独立的名为strings的XML文件中,虽然可以硬编码设置组件的文本属性,如android:text="True",但这通常不是个好方法。将文字内容放置在独立的字符串资源XML文件中,然后引用它们才是好方法。在第15章中,我们将学习如何使用字符串资源轻松实现本地化。 需要在activity_quiz.xml文件中引用的字符串资源目前还不存在。现在我们来添加这些资源。 1.4.3 创建字符串资源 每个项目都包含一个名为strings.xml的默认字符串文件。 在包浏览器中,找到res/values目录,点击小三角显示目录内容,然后打开strings.xml文件。忽略图形界面,在编辑区底部选择strings.xml标签页,切换到代码界面。 可以看到,项目模版已经默认添加了一些字符串资源。删除不需要的hello_world部分,添加应用布局需要的三个新的字符串,如代码清单1-3所示。 代码清单1-3 添加字符串资源(strings.xml) (项目已默认配置好应用菜单,请勿删除menu_settings字符串设置,否则将导致与应用菜单相关的其他文件发生版式错误。) 现在,在GeoQuiz项目的任何XML文件中,只要引用到@string/false_button,应用运行时,就会得到文本“False”。 保存strings.xml文件。这时,activity_quiz.xml布局曾经提示缺少字符串资源的信息应该不会再出现了。(如仍有错误信息,那么检查一下这两个文件,确认是否存在输入或拼写错误。) 字符串文件默认被命名为strings.xml,当然也可以按个人喜好任意取名。一个项目也可以有多个字符串文件。只要这些文件都放置在res/values/目录下,并且含有一个resources根元素,以及多个string子元素,字符串定义即可被应用找到并得到正确使用。 1.4.4 预览界面布局 至此,应用的界面布局已经完成,现在我们使用图形布局工具来进行实时预览。首先,确认保存了所有相关文件并且无错误发生,然后回到activity_quiz.xml文件,在编辑区底部选择图形布局标签页进行界面布局预览,如图1-11所示。 图1-11 在图形布局工具中预览界面布局(activity_quiz.xml)