布局与控件 第9节 ListView

更新时间 修改意见
2016-08-02 陈敏

第9节 ListView

在应用界面当中,经常需要使用列表来展示内容。
Android SDK提供了ListView控件,来实现这种效果。

ListView需要和Adapter配合使用,ListView负责内容的显示,Adapter负责为ListView提供要展示的数据。

列表的设计采用了将数据与展示分离的模式-数视分离。ListView负责数据的展现,Adapter负责向ListView提供要展示的数据,以及每条列表上的数据如何显示。

这是程序设计中常常用到的一种设计方法。这一章节我们主要介绍ListView,而它的搭档Adapter将放到下一章节详细介绍,所以现在我们只需要知道Adapter用来存放数据、规定每条列表项长什么样子。

9.1 ListView的使用方法

使用ListView展示内容,通常分下面几个步骤,

  1. 在布局文件中设置ListView布局;

  2. 在Activity界面创建的时候(例如onCreate()当中),通过代码获取ListView

  3. 创建一个Adapter负责为ListView提供数据。Android SDK提供了很多类型的AdapterArrayAdapter CursorAdapter SimpleAdapter等等,它们都是BaseAdapter的子类,简化了Adapter的使用。要显示的数据和显示这项数据项的布局要设置给Adapter

    Android SDK提供了一些常用的数据项布局方式android.R.layout.simple_list_item_1 android.R.layout.simple_list_item_2等等。我们也可以自己设计每一项的布局方式,后面会讲到。

  4. Adapter设置给ListView,数据将以列表的形式被展示,

  5. 为显示的每个item添加,点击时代响应处理函数;

综合以上的代码,就是,

运行以后,就能看到a b c以列表的形式,在界面上展现出来了。

9.2 ListView内容的更新

如果需要展示的数据有变化,就需要更新ListView,需要注意,

  1. 界面的更新需要在主线程进行(UI线程),如果在其他线程更新,系统有可能报错,并提示你“不能在非UI线程更新界面元素”;
  2. 修改了Adapter中要展示的数据后,需要使用AdapternotifyDataSetChanged(),界面就会刷新,看到修改的效果;

例如,初始化显示列表,并显示内容

主线程中更新数据,并刷新,

9.3 常用效果

9.3.1 修改点按时的背景效果

列表项的背景颜色是可以根据点按的不同状态而变化的,例如点击列表项的时候,背景颜色变深一点,出于选中的状态,背景颜色与别的项不同等等。
这一切只需要为ListViewlistSelector属性设置上一个Selector就好了,例如,

其中,@color/normalres/values/colors.xml中,被设计成,

使用的时候就像这样,

大多数时候,希望那些没有被选中的列表项的背景颜色能和选中了但是没有被点击的列表项颜色一致,例如上面d列表项的背景要和c列表项没有被点击时一个颜色,那么可以为ListView的背景设置一个与没有点击的一样的颜色,

这里有个非常重要的地方需要注意:对于ListView来说,只有当列表项被点击(press)或者获取焦点(focus)的时候,它对应的列表项才会被使用ListView设置的这个Selector

所以对于那些没有被点击或者没有获取焦点的数据项,即使它们满足Selector中的某些条件,Selector也将完全不起作用。

9.3.2 修改分隔线

ListView中每一个列表项之间的分隔栏是可以进行调整的,可以通过android:divider属性设定它的颜色,通过android:dividerHeight属性设定它的高度,

9.3.3 添加header和footer

ListView的顶部和底部,可以各添加上自定义栏。不过添加的过程需要在代码中进行,

  1. 用java代码或者xml的方式,创建要添加到header或者footer的界面;
  2. 使用addHeaderView()将header界面添加到ListView的顶部;
  3. 使用addFooterView()将footer界面添加到ListView的底部;

9.3.4 ScrollBar

假如列表中的数据比较多,而用户又在上下滑动列表的时候,左边会出现一个滚动条,用来指示当前看到的内容在整个列表的比例位置。

可以通过android:scrollbars属性来设置这个bar是否需要显示,

  1. none:永远不显示;
  2. vertial:需要的时候显示在右边栏;
  3. horizontal:需要的时候显示在下边栏;

9.3.5 FastScroller

当列表中的数据非常多的时候,可以通过设置android:fastScrollEnabled属性,来启动FastScroller。可以让用户拖动右边的滑块,加快浏览的速度。不过,假如列表项不能占满4个屏幕的高度,那么即使设置了android:fastScrollEnabled属性,FastScroller也是不会出现的。毕竟数据少,也就不需要Fastscroller出马了。

Fastscroller的滑块和轨道是可以自定义的,在应用的主题中设定android:fastScrollTrackDrawableandroid:fastScrollThumbDrawable属性,就可以做出修改,

9.4 ListView的Choice Mode

ListView本身带有单选和多选功能,也就是说在单选模式下,它能够记住当前选中的唯一的列表项;在多选模式下,它能够记住目前选取的所有的列表项。

这种选择模式共有4种CHOICE_MODE_NONE CHOICE_MODE_SINGLE CHOICE_MODE_MULTIPLE CHOICE_MODE_MULTIPLE_MODAL

使用setChoiceMode()函数,就可以设置ListView的选择模式。

9.4.1 CHOICE_MODE_NONE

这是ListView默认的选择模式,当使用者点击列表项后,不会将任何点击的列表项当成被选择上的列表项。

9.4.2 CHOICE_MODE_SINGLE

使用这个选项模式,当使用者点击列表项后,会将最后一次点击的列表项当成被选择上的列表项。

每次点击列表项,可以在它的监听函数中得知哪个列表项被点击了,

以后就可以通过ListViewgetCheckedItemPositions()获取被选中的数据项的位置列表,

例如,当列表项按照序号为3->2->1-7的顺序被点击后,7将被记录下来,作为当前被选中的数据项。调用getCheckedItemPositions()后,将得到一个键值对,里面只会记录,

这里为了看到被选中的效果,采用了Android SDK提供的android.R.layout.simple_list_item_single_choice布局,作为列表项的布局。

9.4.3 CHOICE_MODE_MULTIPLE

使用这个选项模式,当使用者点击列表项后,会将所有点击的列表项当成被选择上的列表项。

每次点击列表项,可以在它的监听函数中得知哪个列表项被点击了,

通过ListViewgetCheckedItemPositions()获取被选中的数据项的位置列表,

例如,当列表项按照序号为3->2->1->7的顺序被点击后,3 2 1 7将被记录下来,作为当前被选中的数据项。调用getCheckedItemPositions()后,将得到一个个键值对,里面会记录,

这些记录,将按照列表项的位置从小到大排列。

如果用户在已经被选上的数据项上,又再次点击,这将取消对它的选择。例如,当列表项按照序号为3->2->1->7->2->1的顺序被点击后,就变成了,

对于被取消了选择的列表项,并不会从记录中移除,而是改变它的值成false

这里为了看到被选中的效果,采用了Android SDK提供的android.R.layout.simple_list_item_multiple_choice布局,作为列表项的布局。

9.4.4 CHOICE_MODE_MULTIPLE_MODAL

CHOICE_MODE_MULTIPLE_MODAL模式中,用户必须通过长按任意一个列表项,进入多选模式,否则不能进行多选。

这个模式的使用与CHOICE_MODE_MULTIPLE类似,不过它需要设置一个ActionMode,这样才能在长按列表项后,改变ActionBar的菜单栏,打开多选的菜单。

  1. 实现ListViewMultiChoiceModeListener接口,

  2. 使用创建的接口,传递给ListView

CHOICE_MODE_MULTIPLE_MODAL模式下,对列表项的点击,是在ListView.MultiChoiceModeListeneronItemCheckedStateChanged()函数中响应的。

这里为了看到被选中的效果,采用了Android SDK提供的android.R.layout.simple_list_item_multiple_choice布局,作为列表项的布局。

9.4.5 关于单选和多选的状态背景

前面的演示中,分别对不同的选择模式,使用了不同的数据项布局,

我们也可以选择自己的布局来实现。但是不管使用什么布局,我们都希望被选上的列表项有特别的效果,和其他没有被选上的数据项区别开。这里有两种方案,

  1. 使用实现了Clickable接口的控件或者布局,作为数据项的布局。例如前面我们使用的android.R.layout.simple_list_item_multiple_choice android.R.layout.simple_list_item_single_choice等,它们本身就是CheckedTextView。当点击它们的时候,它们就自带了勾选框,可以看到效果。

    所以,可以选择CheckBox Switch这类同样实现了Clickable接口的布局来表现;也可以自定义一个实现了Clickable接口的布局。这里用android.R.layout.simple_list_item_multiple_choice的实现来举个例子,

  2. 给数据项的布局使用一个Selector,告诉这个布局,当它被activated以后要怎么显示。比如,定义一个布局custom_item_layout.xml,

    给这个布局设计一个selector,增加对android:activated属性的设置,

    使用这个这个布局,

    当我们多选的时候,那些选中项,就变成黄色,看到如下的界面,


/**************************************************************************/
* 版权声明
* 本教程只在CSDN安豆网发布,其他网站出现本教程均属侵权。
/
**************************************************************************/