
7.1 列表类组件
在Android中提供了两种列表类组件:一种是下拉列表框,通常用于弹出一个下拉菜单供用户选择,用Spinner表示;另一种是列表视图,通常用于实现在一个窗口中只显示一个列表,使用ListView表示,它们的继承关系如图7.1所示。
从图7.1中可以看出,Spinner和ListView组件都间接继承自ViewGroup,所以它们都属于容器类组件。而由于它们又间接继承自AdapterView,所以它们都可以采用合适的方式显示多个列表项。下面将对这两个组件分别进行介绍。

图7.1 列表类组件继承关系图
7.1.1 下拉列表框
Android中提供的下拉列表框(Spinner)通常用于提供一系列列表项供用户进行选择。例如,豆瓣网搜索界面中的选择搜索类型的下拉列表框,以及手机相册的选择相片显示方式的下拉列表框。
在Android中,在XML布局文件中通过<Spinner>标记添加下拉列表框,基本语法格式如下。

其中,android:entries为可选属性,用于指定列表项,如果在布局文件中不指定该属性,可以在Java代码中通过为其指定适配器的方式指定;android:prompt属性也是可选属性,用于指定下拉列表框的标题。
说明
在Android 5.0中,当采用默认的主题(Theme.Holo)时,设置android:prompt属性看不到具体的效果,如果采用Theme.Black,就可以在弹出的下拉列表框中显示该标题。
通常情况下,如果下拉列表框中要显示的列表项是可知的,那么可将其保存在数组资源文件中,然后通过数组资源来为下拉列表框指定列表项。这样,就可以在不编写Java代码的情况下实现一个下拉列表框。下面将通过一个具体的实例来说明如何在不编写Java代码的情况下,在屏幕中添加下拉列表框。
【例7.01】 豆瓣网搜索下拉列表框(实例位置:资源包\源码\07\7.01)
在Android Studio中创建Module,名称为Spinner,实现本实例的具体步骤如下。
(1)修改新建Module的res\layout目录中的布局文件activity_main.xml。首先将默认添加的布局管理器修改为水平线性布局管理器,然后在布局文件中添加一个<spinner>标记,并为其指定android:entries属性,最后添加一个EditText组件,将需要的背景图片复制到mipmap-mdpi文件夹中,具体代码如下。

(2)编写用于指定列表项的数组资源文件,并将其保存在res\values目录中,这里将其命名为arrays.xml,在该文件中添加一个字符串数组,名称为ctype,具体代码如下。

(3)打开主活动MainActivity,修改默认生成的代码,让MainActivity直接继承Activity,并导入android.app.Activity类,修改后的关键代码如下。

(4)打开AndroidManifest.xml文件,将其中的<application>标记的android:theme属性值@style/AppTheme修改为@style/Theme.AppCompat.Light.DarkActionBar,修改后的android:theme属性的代码如下。
android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
(5)添加下拉列表框后,如果需要在用户选择不同的列表项后,执行相应的处理,则可以为该下拉列表框添加OnItemSelectedListener事件监听器。例如,为spinner添加选择列表项事件监听器,并通过getItemAtPosition()方法获取选中的值,然后用Toast.makeText()方法将获取的值显示出来,可以在onCreate()方法中使用下面的代码。

(6)运行本实例,将显示类似豆瓣网搜索页面,单击下拉列表框右侧的黑色倒三角,可以显示下拉列表框的各个列表项,如图7.2所示,选择某一列表项(如电影/电视)后,将显示选择项的值,如图7.3所示。

图7.2 豆瓣网搜索下拉列表框

图7.3 显示选择的结果
在使用下拉列表框时,如果不在布局文件中直接为其指定要显示的列表项,也可以通过为其指定适配器的方式指定。下面仍然以例7.1为例介绍通过指定适配器的方式指定列表项的方法。
为下拉列表框指定适配器,通常分为以下3个步骤。
(1)创建一个适配器对象,通常使用ArrayAdapter类。首先需要创建一个一维的字符串数组,用于保存要显示的列表项,然后使用ArrayAdapter类的构造方法ArrayAdapter(Context context, int textViewResourceId, T[] objects)实例化一个ArrayAdapter类的实例,具体代码如下。

(2)为适配器设置列表框下拉时的选项样式,具体代码如下。
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
(3)将适配器与下拉列表框关联,具体代码如下。

在屏幕上添加下拉列表框后,可以使用下拉列表框的getSelectedItem()方法获取下拉列表框的选中值,例如,要获取下拉列表框选中项的值,可以使用下面的代码:

7.1.2 列表视图
列表视图(ListView)是Android中最常用的一种视图组件,它以垂直列表的形式列出需要显示的列表项。例如,微信通讯录界面中的联系人列表,以及QQ的图片浏览设置界面。
在Android中,可以通过在XML布局文件中使用<ListView>标记添加列表视图,其基本语法格式如下。

ListView组件支持的常用XML属性如表7.1所示。
表7.1 ListView组件支持的XML属性

例如,在布局文件中添加一个列表视图,并通过数组资源为其设置列表项,具体代码如下。

在上面的代码中,使用了名称为ctype的数组资源,因此,需要在res\values目录中创建一个定义数组资源的XML文件arrays.xml,并在该文件中添加名称为ctype的字符串数组,关键代码如下。

运行上面的代码,将显示如图7.4所示的列表视图。

图7.4 在布局文件中添加的列表视图
在使用列表视图时,重要的是如何设置选项内容。同Spinner下拉列表框一样,如果没有在布局文件中为ListView指定要显示的列表项,也可以通过为其设置Adapter来指定需要显示的列表项。通过Adapter来为ListView指定要显示的列表项,可以分为以下两个步骤。
(1)创建Adapter对象。对于纯文字的列表项,通常使用ArrayAdapter对象。创建ArrayAdapter对象通常可以有两种方式:一种是通过数组资源文件创建;另一种是通过在Java文件中使用字符串数组创建。这与7.1.1节Spinner下拉列表框中介绍的创建ArrayAdapter对象基本相同,所不同的就是在创建该对象时,指定列表项的外观形式。在Android API中默认提供了一些用于设置外观形式的布局文件,通过这些布局文件,可以很方便地指定ListView的外观形式。常用的布局文件有以下几个。
simple_list_item_1:每个列表项都是一个普通的文本。
simple_list_item_2:每个列表项都是一个普通的文本(字体略大)。
simple_list_item_checked:每个列表项都有一个已选中的列表项。
simple_list_item_multiple_choice:每个列表项都是带复选框的文本。
simple_list_item_single_choice:每个列表项都是带单选按钮的文本。
(2)将创建的适配器对象与ListView相关联,可以通过ListView对象的setAdapter()方法实现,具体代码如下。
listview.setAdapter(adapter); //将适配器与ListView关联
下面通过一个具体的实例演示通过适配器指定列表项来创建ListView。
【例7.02】 模拟支付宝朋友列表(实例位置:资源包\源码\07\7.02)
在Android Studio中创建Module,名称为Alipay Friends。在该Module中实现本实例,具体步骤如下。
(1)修改新建Module的res\layout目录下的布局文件activity_main.xml,将默认添加的布局管理器修改为相对布局管理器,将默认添加的TextView组件删除,添加一个ListView组件,用于显示朋友列表,关键代码如下。

(2)在新建项目的res\layout目录下右击新建一个布局文件,命名为item,用来显示图片、名称以及信息内容,具体代码如下。

(3)打开主活动MainActivity,修改默认生成的代码,让MainActivity直接继承Activity,并导入android.app.Activity类,然后分别定义图标数组、名字数组、信息数组。
(4)在主活动的onCreate()方法中,首先获取布局文件中添加的ListView,然后创建一个List集合,通过for循环将图标、名字、信息放到Map中,并添加到List集合中,关键代码如下。

(5)创建SimpleAdapter适配器,并且将适配器与ListView关联,为ListView创建监听事件,然后通过getItemAtPosition()方法获取选中的值,最后通过Toast.makeText()方法将获取的值显示出来,具体代码如下。

(6)运行本实例,将显示如图7.5所示的运行结果。

图7.5 支付宝朋友列表