Android 7应用程序开发教程
上QQ阅读APP看书,第一时间看更新

4.2 使用XML定义视图

在使用XML构建一个用户界面之前,我们需要重温一下Android工程的目录结构。如图4.2所示,以HelloAndroid为例,project视图列出了工程的目录结构。以.开头的目录是AS生成的辅助目录,无须用户干预。HelloAndroid文件夹是模块目录,编程工作主要集中在这个目录中,相当于使用Eclipse构建的工程文件夹,包含build、src、res等文件夹。其中,res目录为Android工程中所使用的资源目录,用户UI所涉及的资源基本都放置在该目录下。res目录下的每一项资源文件都会由AAPT(Android Asset Packaging Tool)为其生成一个对应的public static final类型的ID号,放置到build目录下的R.java文件中,Android系统根据该ID号来访问对应资源。build目录由AS自动生成,不需要用户修改,由系统维护。res/drawable/目录用来存放工程中使用到的图片文件,drawable之后的hdpi、ldpi、mdpi分别放高分辨率、低分辨率和中分辨率的图片以适应不同分辨率的手机,Android系统会根据用户手机的配置信息自动选取合适分辨率的图片文件,无须程序员干预;res/layout/目录下存放着定义UI布局文件用的XML文件,默认文件名为main.xml;res/values/目录下存放着用于存储工程中所使用到的一些字符串信息的文件,默认文件名为strings.xml。当然,每个目录下都可以存放多个XML文件,可由开发者自行创建。由此可见,Android工程中使用的用户UI设计以及用户UI中涉及的字符串都是由XML文件来存储的。Android系统使用XML文件来定义用户视图。

图4.2 Android工程的目录结构

单击打开values文件夹下的string.xml文件显示出如下代码:

文件的开头部分<?xml version="1.0" encoding="utf-8"?>定义了XML的版本号和字符编码,这个部分在所有的XML文件中都会有,由系统自动添加,不需要修改。<resources>标签定义了hello和app_name两个变量,可以被HelloAndroid工程直接使用。当该文件被修改时,gen目录下的R.java文件也会跟随进行更新。

双击main.xml文件,代码如下:

<LinearLayout>标签定义了当前视图使用的是LinearLayout布局,也叫作线性布局,这是最常用的布局方式,Android SDK还提供其他的几种布局方式,我们会在后面的章节中进行详细的介绍。在<LinearLayout>标签中定义了该布局方式的相关属性。android: layout_width="fill_parent"和android:layout_height="fill_parent"表示该布局的宽和高充满整个手机屏幕,android:orientation="vertical"表示该布局中所放入的组件的排列方式为纵向排列。

在<LinearLayout ...>和</LinearLayout>之间可以添加各种UI组件并设置组件的相关属性,例如组件的高度、宽度、内容等,在4.4节会详细介绍各种常见组件的使用方法。在HelloAndroid实例中添加的是一个TextView组件,相当于一个显示内容的标签。android:layout_width="fill_parent"指定其宽度覆盖满容器的宽,android:layout_height= "wrap_content"指定其高度跟随其显示内容变化。android:id="@id/textView1"指明该TextView的ID值为R.java文件中ID类的成员常量textView1。Android SDK提供了@[<package_ name>:]<resource_type>/<resource_name>方式,以便于从XML文件中访问工程的资源。android:text="@string/hello"指明该TextView组件显示的内容为资源文件string.xml中定义的hello变量的内容。android:text属性也可以直接指定要显示的字符串,但是在实际的工程开发过程中不鼓励这种方式,而应该使用资源文件中的变量,因为这样便于工程维护和国际化。在本书中,为了节省篇幅,部分显示内容简单的组件使用了字符串直接赋值的方法。

Android工程中使用到的资源文件都会在gen目录下的R.java中生成对应项,由系统为每个资源分配一个十六进制的整型数值,唯一标明每个资源。

HelloAndroid工程中的R.java文件代码如下:

由该文件可见,R为静态最终类。其中public static final class layout代表的是res/layout文件夹的内容,layout类的每个整型常量代表该文件夹下的一个XML布局文件。例如,public static final int main代表的是main.xml文件,0x7f030000为系统main.xml文件生成的整型数值。在Android工程中根据该数值找到main.xml文件。public static final class string代表的是res/values/strings.xml文件,string类中的每个整型常量型成员代表strings.xml文件中定义的一个变量。例如,public static final int app_name代表strings.xml中定义的app_name变量,public static final int hello代表stings.xml文件中定义的hello变量。

在工程开发过程中,可以通过[<package_name>.]R.<resource_type>.<resource_name>方式来访问R中定义的任意资源。其中package_name为资源文件被放置的包路径,一般可以省略。resource_type为资源类型,例如layout、string、color、drawable、menu等。resource_ name指的是为资源文件在类中定义的整型常量的名字,例如:

     setContentView(R.layout.main);

这行代码中,通过R.layout.main找到了布局文件main.xml,并通过setContentView方法将其设置为当前Activity的视图。要从视图中查找某个组件,需要使用findViewById方法,通过组件ID获取组件的对象。例如,要获取main.xml中的TextView组件对象,需要执行以下代码:

     TextView textview=(TextView)findViewById(R.id.textView1);