吸引用户的眼球,是我们至死不渝的追求;
      第一时间呈现最有价值的信息,简明大方,告诉客户,你的选择是多么的明智,这正是你寻觅已久的东西。
      分组的应用场合还是很多的,有数据集合的地方往往要分组显示;
      分组的形式也很多,最常见的就是镶嵌在列表中,网上说的很多ExpandListView的也是一种。
      Android自带的通讯录中的联系人是按照拼音首字母(A,B,C,D......)分组分类的,效果如下:
<ignore_js_op>       我们今天也是要实现这样类似的一个效果。
1.样本数据:
      为了突出重点,直击要点,这里提供一个整理好的数据样本:
  1. //list:数据集合
  2. private List<String> list = new ArrayList<String>();
  3. //listTag:Tag集合,其中Tag是分类的分割标签,每个分组的header
  4. private List<String> listTag = new ArrayList<String>();
  5. public void setData(){
  6. list.add("A");
  7. listTag.add("A");
  8. for(int i=0;i<3;i++){
  9. list.add("阿凡达"+i);
  10. }
  11. list.add("B");
  12. listTag.add("B");
  13. for(int i=0;i<3;i++){
  14. list.add("比特风暴"+i);
  15. }
  16. list.add("C");
  17. listTag.add("C");
  18. for(int i=0;i<30;i++){
  19. list.add("查理风云"+i);
  20. }
  21. }

复制代码

2.Activity布局准备:
      放置一个listView来呈现数据。
      group_list_activity.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical"
  4. android:layout_width="fill_parent"
  5. android:layout_height="fill_parent"
  6. >
  7. <!--简单的列表显示-->
  8. <ListView android:id="@+id/group_list"
  9. android:layout_width="fill_parent"
  10. android:layout_height="fill_parent"
  11. android:cacheColorHint="#00000000"/>
  12. </LinearLayout>

复制代码

3.自定义Adapter(本文继承ArrayAdapter):
     这个是本文的重点和核心。 
     Adapter接口为数据和界面搭建了一个访问的桥梁,最重要的就是getView()方法,用这个方法我们可以实现一定程度的界面自定义。
     ArrayAdapter间接实现了Adapter接口,这里我们简单起见,数据源只是提供单一的String数组。

  1. private static class GroupListAdapter extends ArrayAdapter<String>{
  2. //存放标签的列表,用来判断数据项的类型
  3. //如果数据项在标签列表中,则是标签项,否则是数据项
  4. private List<String> listTag = null;
  5. public GroupListAdapter(Context context, List<String> objects, List<String> tags) {
  6. super(context, 0, objects);
  7. this.listTag = tags;
  8. }
  9. @Override
  10. public View getView(int position, View convertView, ViewGroup parent) {
  11. ... ....
  12. }
  13. }

复制代码

我们来看看getView方法:

  1. //该方法根据adapter的顺序一行一行的组织列表
  2. //其中position表示第几行,也就是当前行在adapter的位置,
  3. //convertView表示第几行的View
  4. View getView(int position, View convertView, ViewGroup parent);

复制代码

现在我们就是要重写getView方法,来实现列表中嵌入分组标签。
     分组标签也是列表数据项之一,也是被一行一行的画上去的,但是它和其他数据项UI是不一致的,所以我们需要准备2套数据项布局模板:
     数据项模板group_list_item.xml:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="horizontal"
  4. android:layout_width="fill_parent"
  5. android:layout_height="wrap_content"
  6. android:padding="5dip">
  7. <!-- 图片和文字 -->
  8. <!-- 随便放了一张图片,稍微美化一下 -->
  9. <ImageView
  10. android:src="@drawable/list_icon"
  11. android:layout_width="wrap_content"
  12. android:layout_height="wrap_content"/>
  13. <TextView
  14. android:id="@+id/group_list_item_text"
  15. android:layout_width="wrap_content"
  16. android:layout_height="fill_parent"
  17. android:paddingLeft="5dip"
  18. android:gravity="center_vertical"/>
  19. </LinearLayout>

复制代码

标签项模板group_list_item_tag.xml:

  1. <!-- 只有文字,但是高度小店,背景色设置为555555灰色 -->
  2. <?xml version="1.0" encoding="utf-8"?>
  3. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  4. android:layout_width="fill_parent"
  5. android:layout_height="wrap_content"
  6. android:background="#555555"
  7. android:paddingLeft="10dip">
  8. <TextView
  9. android:id="@+id/group_list_item_text"
  10. android:layout_width="wrap_content"
  11. android:layout_height="20dip"
  12. android:textColor="#ffffff"
  13. android:gravity="center_vertical"/>
  14. </LinearLayout>

复制代码

好,我们现在把这两个模板应用到getView方法中去:

  1. @Override
  2. public View getView(int position, View convertView, ViewGroup parent) {
  3. View view = convertView;
  4. //根据标签类型加载不通的布局模板
  5. if(listTag.contains(getItem(position))){
  6. //如果是标签项
  7. view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item_tag, null);
  8. }else{
  9. //否则就是数据项了
  10. view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item, null);
  11. }
  12. //显示名称
  13. TextView textView = (TextView) view.findViewById(R.id.group_list_item_text);
  14. textView.setText(getItem(position));
  15. //返回重写的view
  16. return view;
  17. }

复制代码

4.禁止标签项的响应事件:
      在ArrayAdapter的父类BaseAdapter中提供了isEnable的()方法,我们看看这个方法:

  1. //默认情况,如果这个方法不是分割符,返回true
  2. //分隔符是无选中和无点击事件的
  3. //说白了,你想不想把改position项当做分隔符,想的话就返回false,否则返回true
  4. public boolean isEnabled (int position)

复制代码

这个方法刚好用来禁用标签项的响应事件。具体实现如下:

  1. @Override
  2. public boolean isEnabled(int position) {
  3. if(listTag.contains(getItem(position))){
  4. return false;
  5. }
  6. return super.isEnabled(position);
  7. }

复制代码

    现在标签项不会再有任何触控效果了,犹如一块死木板。
5.完整代码:
      整个Activity和Adapter代码如下:
  1. public class GroupListActivity extends Activity {
  2. private GroupListAdapter adapter = null;
  3. private ListView listView = null;
  4. private List<String> list = new ArrayList<String>();
  5. private List<String> listTag = new ArrayList<String>();
  6. @Override
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.group_list_activity);
  10. setData();
  11. adapter = new GroupListAdapter(this, list, listTag);
  12. listView = (ListView)findViewById(R.id.group_list);
  13. listView.setAdapter(adapter);
  14. }
  15. public void setData(){
  16. list.add("A");
  17. listTag.add("A");
  18. for(int i=0;i<3;i++){
  19. list.add("阿凡达"+i);
  20. }
  21. list.add("B");
  22. listTag.add("B");
  23. for(int i=0;i<3;i++){
  24. list.add("比特风暴"+i);
  25. }
  26. list.add("C");
  27. listTag.add("C");
  28. for(int i=0;i<30;i++){
  29. list.add("查理风云"+i);
  30. }
  31. }
  32. private static class GroupListAdapter extends ArrayAdapter<String>{
  33. private List<String> listTag = null;
  34. public GroupListAdapter(Context context, List<String> objects, List<String> tags) {
  35. super(context, 0, objects);
  36. this.listTag = tags;
  37. }
  38. @Override
  39. public boolean isEnabled(int position) {
  40. if(listTag.contains(getItem(position))){
  41. return false;
  42. }
  43. return super.isEnabled(position);
  44. }
  45. @Override
  46. public View getView(int position, View convertView, ViewGroup parent) {
  47. View view = convertView;
  48. if(listTag.contains(getItem(position))){
  49. view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item_tag, null);
  50. }else{
  51. view = LayoutInflater.from(getContext()).inflate(R.layout.group_list_item, null);
  52. }
  53. TextView textView = (TextView) view.findViewById(R.id.group_list_item_text);
  54. textView.setText(getItem(position));
  55. return view;
  56. }
  57. }
  58. }

复制代码

6.最终效果:
<ignore_js_op>

本文作者:谦虚的天下

Android学习系列(9)--App列表之分组ListView的更多相关文章

  1. Android学习系列(17)--App列表之圆角ListView(续)

    http://www.cnblogs.com/qianxudetianxia/archive/2011/09/19/2068760.html   本来这篇文章想并到上篇Android学习系列(16)- ...

  2. Android学习系列(15)--App列表之游标ListView(索引ListView)

    游标ListView,提供索引标签,使用户能够快速定位列表项.      也可以叫索引ListView,有的人称也为Tweaked ListView,可能更形象些吧.      一看图啥都懂了: 1. ...

  3. Android学习系列(16)--App列表之圆角ListView

    有些东西看多了,就厌烦了:extjs对我这种感觉最为强烈.甚至,有时觉得设计之殇是审美疲劳.直角看多了,就想看看圆角,不知何时,这几年刮起了一阵阵的圆角设计风:CSS新标准纳入圆角元素,iphone中 ...

  4. Android学习系列(11)--App列表之拖拽ListView(下)

    接着上篇Android学习系列(10)--App列表之拖拽ListView(上)我们继续实现ListView的拖拽效果. 7.重写onTouchEvent()方法.     在这个方法中我们主要是处理 ...

  5. Android学习系列(10)--App列表之拖拽ListView(上)

     研究了很久的拖拽ListView的实现,受益良多,特此与尔共飨.      鉴于这部分内容网上的资料少而简陋,而具体的实现过程或许对大家才有帮助,为了详尽而不失真,我们一步一步分析,分成两篇文章. ...

  6. Android学习系列(12)--App列表之拖拽GridView

    根据前面文章中ListView拖拽的实现原理,我们也是很容易实现推拽GridView的,下面我就以相同步骤实现基本的GridView拖拽效果.     因为GridView不用做分组处理,代码处理起来 ...

  7. Android学习系列(18)--App工程结构搭建

     本文算是一篇漫谈,谈一谈关于Android开发中工程初始化的时候如何在初期我们就能搭建一个好的架构.      关于android架构,因为手机的限制,目前我觉得也确实没什么大谈特谈的,但是从开发的 ...

  8. Android学习系列(37)--App调试内存泄露之Context篇(下)

    接着<Android学习系列(36)--App调试内存泄露之Context篇(上)>继续分析. 5. AsyncTask对象 我N年前去盛大面过一次试,当时面试官极力推荐我使用AsyncT ...

  9. Android学习系列(7)--App轮询服务器消息

    这篇文章是android开发人员的必备知识. 1.轮询服务器     一般的应用,定时通知消息可以采用轮询的方法从服务器拿取消息,当然实时消息通知的话,建议采用推送服务.    其中需要注意轮询的频率 ...

随机推荐

  1. leetcode笔记:Same Tree

    一. 题目描写叙述 Given two binary trees, write a function to check if they are equal or not. Two binary tre ...

  2. C++迭代器失效的几种情况总结

    一.序列式容器(数组式容器) 对于序列式容器(如vector,deque),序列式容器就是数组式容器,删除当前的iterator会使后面所有元素的iterator都失效.这是因为vetor,deque ...

  3. 使用Kindeditor上传图片

    给客户制作的项目中需要添加富文本,从网上看了一下很多人推荐kindeditor这个编辑器,用了之后也感觉不错,有一些问题的就是上传图片的时候遇到了一些问题,在这里记录一下,也方便以后查看. 首先在官网 ...

  4. Android -- 在ScrollView中嵌套ListView

    在做一个工程,这个工程的布局可以相当的复杂,最外面是ScrollView,在ScrollView里面有两个Listview,这下好了,布局出来了,放在机子上跑,卡得想死有木有,信息乱跑乱出现,表示非常 ...

  5. Oracle服务启动顺序导致ORA-12514

    在window 上装了oracle11g,按照常规步骤安装完成后一切OK,如下图所示 C:\Users\Administrator>sqlplus /nolog SQL*Plus: Releas ...

  6. [Javascript] Function Expression Ex, Changing Declarations to Expressions

    Inside the Haunted Hickory House file, developers for the Forest of Function Expressions Theme Park ...

  7. 2. Using 'dp' instead of 'px' to set text size

    android:textSize="45px"  ==> android:textSize="45dp" 因为Android Phone的手机分辨率各不相 ...

  8. nGrinder3.4 性能测试框架安装

    转载:https://blog.csdn.net/mbugatti/article/details/53782070 nGrinder3.4 (2016.05.24) 支持JDK1.8 github地 ...

  9. python多线程概念

    转自:http://www.cnblogs.com/fnng/p/3489321.html 在使用多线程之前,我们首页要理解什么是进程和线程. 什么是进程? 计算机程序只不过是磁盘中可执行的,二进制( ...

  10. hdu4848 求到达每一个点总时间最短(sum[d[i]])。

    開始的时候是暴力dfs+剪枝.怎么也不行.后来參考他人思想: 先求出每一个点之间的最短路(这样预处理之后的搜索就能够判重返回了).截肢还是关键:1最优性剪枝(尽量最优:眼下的状态+估计还有的最小时间& ...