效果与系统的联系人分组效果类似,组头有挤压效果。但是不同的是,SectionListView支持每组的组头布局自定义,每组的内容布局也可以自定义。

效果图如下:

自定义Adapter:

package com.hiphonezhu.demo.lib;import java.util.HashMap;
import java.util.Map;import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
/*** 带分组功能的Adapter* @author hiphonezhu@gmail.com* @version [TestAndroid, 2015-2-16]*/
public abstract class SectionAdapter extends BaseAdapter
{private Map<Integer, Integer> sectionPositionMap; // 存储分组编号及对应的改组内的条目数量private Map<Integer, Integer> sectionForPositionMap = new HashMap<Integer, Integer>(); // 存储position对应的分组编号private Map<Integer, Integer> positionForSectionMap = new HashMap<Integer, Integer>(); // 存储分组编号对应的第一个出现的positon位置public SectionAdapter(Map<Integer, Integer> sectionPositionMap){this.sectionPositionMap = sectionPositionMap;// 初始化Position与Section对应关系数据int sectionSize = sectionPositionMap != null? sectionPositionMap.size() : 0;int position = 0;for(int i = 0; i < sectionSize; i++){int size = sectionPositionMap.get(i) != null? sectionPositionMap.get(i) : 0;for(int j = 0; j < size; j++){if (!positionForSectionMap.containsKey(i)){positionForSectionMap.put(i, position);}sectionForPositionMap.put(position, i);position++;}}}@Overridepublic View getView(int position, View convertView, ViewGroup parent){int type = getItemViewType(position);return getView(type, position, convertView, parent);}/*** 加载每一行的View* @param section 分组编号* @param position* @param convertView* @param parent* @return*/protected abstract View getView(int section, int position, View convertView, ViewGroup parent);/*** 根据position返回item的样式(每个分组一种样式)* @param position* @return* @see android.widget.BaseAdapter#getItemViewType(int)*/@Overridepublic int getItemViewType(int position){return getSectionForPosition(position);}/*** 返回样式的总共数量(总计多少分组就多少个样式)* @return* @see android.widget.BaseAdapter#getViewTypeCount()*/@Overridepublic int getViewTypeCount(){return getSectionCount();}@Overridepublic int getCount(){int sectionCount = getSectionCount();int sectionItemTotalCount = 0;for(int i=0; i<sectionCount; i++){sectionItemTotalCount += getCountForSection(i);}return sectionItemTotalCount;}/*** 判断当前行是否要显示分组信息* @param position 下标* @return*/public boolean sectionVisible(int position){int section = getSectionForPosition(position);return position == getPositionForSection(section);}/*** 根据分组号加载分组View* @param section* @return*/public abstract View getSectionView(int section);/*** 根据下标位置查询分组编号* @param position 下标* @return*/public int getSectionForPosition(int position){if (!sectionForPositionMap.containsKey(position)){return -1;}return sectionForPositionMap.get(position);}/*** 根据分组号查找第一个下标位置* @param section 分组编号* @return*/public int getPositionForSection(int section){if (!positionForSectionMap.containsKey(section)){return -1;}return positionForSectionMap.get(section);}/*** 返回分组数量* @return*/protected int getSectionCount(){return sectionPositionMap != null? sectionPositionMap.size() : 0;}/*** 返回指定分组中的item数目* @param section 分组编号* @return*/protected int getCountForSection(int section){return sectionPositionMap != null? (sectionPositionMap.get(section) != null? sectionPositionMap.get(section) : 0) : 0;}
}

自定义ListView:

package com.hiphonezhu.demo.lib;import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.util.AttributeSet;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AbsListView;
import android.widget.ListView;
/*** 带分组表头的ListView* @author hiphonezhu@gmail.com* @version [TestAndroid, 2015-2-16]*/
public class SectionListView extends ListView
{private SectionAdapter sectionAdapter;private ViewGroup sectionContainer;public SectionListView(Context context, AttributeSet attrs, int defStyle){super(context, attrs, defStyle);}public SectionListView(Context context, AttributeSet attrs){super(context, attrs);}public SectionListView(Context context){super(context);}/*** 绑定数据适配器* @param sectionAdapter* @param sectionContainer*/public void setAdapter(SectionAdapter sectionAdapter, ViewGroup sectionContainer){super.setAdapter(sectionAdapter);this.sectionAdapter = sectionAdapter;this.sectionContainer = sectionContainer;setOnScrollListener(scrollListener);}private OnScrollListener scrollListener = new OnScrollListener(){private int lastFirstVisibleItem = -1; final Map<Integer, View> sectionViewMap = new HashMap<Integer, View>();@Overridepublic void onScrollStateChanged(AbsListView paramAbsListView, int paramInt){}@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount,  int totalItemCount){int section = sectionAdapter.getSectionForPosition(firstVisibleItem);int nextSecPosition = sectionAdapter.getPositionForSection(section + 1); View sectionView = sectionViewMap.get(section);if (sectionView == null){sectionView = sectionAdapter.getSectionView(section);sectionViewMap.put(section, sectionView);sectionContainer.addView(sectionView);}else{int count = sectionContainer.getChildCount();for(int i = 0; i < count; i++){if (sectionContainer.getChildAt(i) != sectionView){sectionContainer.getChildAt(i).setVisibility(View.GONE);}else{sectionContainer.getChildAt(i).setVisibility(View.VISIBLE);}}}if (firstVisibleItem != lastFirstVisibleItem) {  MarginLayoutParams params = (MarginLayoutParams) sectionContainer.getLayoutParams();  params.topMargin = 0;  sectionContainer.setLayoutParams(params);  }  if (nextSecPosition - firstVisibleItem < visibleItemCount) // 下一个分组在当前屏幕可见范围{// 下一个分组的ViewView childView = view.getChildAt(nextSecPosition - firstVisibleItem);  if (childView != null) {  int titleHeight = sectionContainer.getHeight();  int top = childView.getTop();  MarginLayoutParams params = (MarginLayoutParams) sectionContainer  .getLayoutParams();  if (top < titleHeight) {  float pushedDistance = top - titleHeight;  params.topMargin = (int) pushedDistance;  sectionContainer.setLayoutParams(params);  } else {  if (params.topMargin != 0) {  params.topMargin = 0;  sectionContainer.setLayoutParams(params);  }  }  }  }lastFirstVisibleItem = firstVisibleItem;  }};
}

源码下载地址:https://github.com/hiphonezhu/SectionListView

强大的分组SectionListView, 支持自定义组头布局和分组的内容布局, 组头有挤压效果相关推荐

  1. 开源自定义表单提交系统源码 支持自定义字段功能强大

    分享一个强大的可以自定义字段的表单提交系统源码,完全开源可以二次开发,支持新建N个表单主题,不限制数量,解决所有表单的应用场景.自定义表单模型,任何类型都支持,功能十分强大. 此套万能表单系统厉害了, ...

  2. ml不是内部或外部命令_美国飞机制造商波音公司采用VR技术训练宇航员 ; Snap Lens Studio推出支持自定义ML驱动的Snapchat镜头...

    看日报是个好习惯!  Valve宣布为Steam开发者推出OpenXR预览版本,支持跨平台VR/AR内容开发  Valve在为Steam游戏开发人员迎接OpenXR面世的准备方面迈出了重要的一步,开发 ...

  3. winform定义数据源名称_WinForm中使用CrystalReport水晶报表——基础,分组统计,自定义数据源...

    开篇 本篇文章主要是帮助刚开始接触CrystalReport报表的新手提供一个循序渐进的教程.该教程主要分为三个部分1)CrystalReport的基本使用方法:2)使用CrystalReport对数 ...

  4. python selenium post请求_工作随笔——selenium支持post请求,支持自定义header

    2018-01-10:fix post 请求数据遗漏部分内容 背景: 最近在写一个小程序,发现博主所在的地区访问该网站时有防ddos功能验证导致程序不能正常工作. 经过试验发现可以用国外代理ip解决这 ...

  5. element form自定义校验_SpringBoot分组校验及自定义校验注解

    前言   在日常的开发中,参数校验是非常重要的一个环节,严格参数校验会减少很多出bug的概率,增加接口的安全性.在此之前写过一篇SpringBoot统一参数校验主要介绍了一些简单的校验方法.而这篇则是 ...

  6. 模拟get和post请求(支持自定义header和测试CDN节点)

    下面是一个模拟get或者post请求的方法支持 1.get,post方法 2.自定义参数 3.自定义header 4.返回服务器的返回内容和header 5.支持相特定的服务器请求url,适合测试cd ...

  7. datatable的数据进行组内排序_Spark实现分组Top-k排序的四种方案(scala语言)

    Spark中实现分组排序(取Top-k)的四种方法. 以求每个学科最受欢迎的老师为例,假设学科下每个老师的主页访问量的多少代表该老师的受欢迎程度. 截取log日志文件中的网址数据的格式为: 数据格式: ...

  8. 服务器阵列卡安装win7系统,乐扩阵列卡IO-PCE9230-4IR组阵列方法和windows7系统安装到阵列组详细讲解(附视频) - 常见问题 - 技术支持 - 乐扩...

    以[乐扩IO-PCE9230-4IR阵列卡]为例,详细讲解组阵列方法,安装Win7 操作系统安装到阵列组的方法: 一.组阵列:[观看视频] 先组阵列: 1.在关机状态下,把阵列卡插到主板的PCI-E插 ...

  9. 开源表单网站系统源码支持自定义字段提交

    分享一个完全开源的自定义表单提交系统源码,功能强大,支持三级联动,支持在线付费报名,带完整搭建教程. 春哥万能自定义表单系统是支持自定义的万能表单系统,支持普通表单.付费报名.预约服务等三合一功能,支 ...

最新文章

  1. Win10系列:JavaScript访问文件和文件夹
  2. 机器学习的教训:5家公司分享的错误经验
  3. CheckBox in ListView
  4. 设计模式示例_责任链设计模式示例
  5. C语言有参函数调用时参数值传递问题
  6. springboot_通过Actuator了解应用程序运行时的内部状况
  7. 玩游戏用什么轴的机械键盘好_机械键盘选什么轴?全方面分析各轴手感和区别...
  8. scala中的柯里化函数
  9. CPU指令集科普:CISC指令集和RISC指令集
  10. python实现九九乘法表代码解释_python编写九九乘法表代码
  11. 快速清理C盘的四个方法
  12. 快速添加百度网盘文件到Aria2 猴油脚本
  13. 又有朋友被骗入传销了!
  14. PyCharm 的调试功能
  15. qt生成程序以管理员身份运行和取消以管理员身份运行方式
  16. 儿童身高体重健康对照表
  17. 一个ppp帧的数据部分(用十六进制写出)是7D 5E FE 27 7D 5D 7D 5D 65 7D 5E。
  18. Juniper设备审计
  19. 这些东西别晒到朋 友 圈,小心惹来祸!
  20. 常见的网络营销技巧有哪些?

热门文章

  1. 浅谈农批市场的信息化:发展现状、信息化动因和契入方向
  2. DA03 – Schemas导论
  3. 统计案例分析之预测社会消费品零售总额
  4. 并发编程之 ThreadLocal 源码剖析
  5. 网络安全系列之三十七 Pangolin(穿山甲)和Havij(胡萝卜)的使用
  6. OT安全|工业控制系统(ICS)六大安全实践
  7. PyQt5 文件保存对话框
  8. photoshop多选文字_60多个Photoshop文字效果教程
  9. 日本IIJ公司在福冈机场开通运营新的数据中心
  10. Android端穿山甲SDK集成