PinnedSectionListView:分组的listView滑动中固定组标题的实现

简介:

在很多应用中,看到这样的listview:listview滑动过程中分组标题固定在上方,当第二个组滑上来时,第一个组才跟着上滑,下一个组固定,直到该组也滑出上边缘。世上无难事只怕有心人,在github上就有人做出来了,而且效果很好(后来发现安卓自带应用中联系人应用就是这样的,估计github的作者也是仿照着联系人做出来的吧)。

先看截图:

    



PinnedSectionListView继承自listview,众所周知listview的每个子view都是按顺序跟着滚动的,要实现联系人listview的效果还真的找不到思路。看了PinnedSectionListView之后,感觉要改造一个现有的控件,一般都是通过重绘子view来实现的。ViewGroup(ListView继承自它)重绘子view的方法是dispatchDraw。

看看PinnedSectionListView在dispatchDraw中有那些特别的处理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Override
protected void dispatchDraw(Canvas canvas) {
     super .dispatchDraw(canvas);
     if (mPinnedSection != null ) {
         // prepare variables
         int pLeft = getListPaddingLeft();
         int pTop = getListPaddingTop();
         View view = mPinnedSection.view;
         // draw child
         canvas.save();
         int clipHeight = view.getHeight() +
                 (mShadowDrawable == null ? 0 : Math.min(mShadowHeight, mSectionsDistanceY));
         canvas.clipRect(pLeft, pTop, pLeft + view.getWidth(), pTop + clipHeight);
         canvas.translate(pLeft, pTop + mTranslateY);
         drawChild(canvas, mPinnedSection.view, getDrawingTime());
         if (mShadowDrawable != null && mSectionsDistanceY > 0) {
             mShadowDrawable.setBounds(mPinnedSection.view.getLeft(),
                     mPinnedSection.view.getBottom(),
                     mPinnedSection.view.getRight(),
                     mPinnedSection.view.getBottom() + mShadowHeight);
             mShadowDrawable.draw(canvas);
         }
         canvas.restore();
     }
}

关键在于canvas.translate(pLeft, pTop + mTranslateY);意思是在绘制mPinnedSection的时候,listview滑动了多长的距离,就将canvas移动多少的距离,使mPinnedSection始终在可见的范围内固定不变。


使用方法:

1.在xml布局文件中将ListView替换成PinnedSectionListView

1
2
3
4
5
<com.hb.views.PinnedSectionListView
     android:id= "@android:id/list"
     android:layout_width= "match_parent"
     android:layout_height= "wrap_content"
     />

2.让你的ListAdapter继承PinnedSectionListAdapter接口,最简单的做法是只增加isItemViewTypePinned方法,该方法必须在item为pinned的情况下返回true。

1
2
3
4
5
6
7
8
9
// Our adapter class implements 'PinnedSectionListAdapter' interface
class MyPinnedSectionListAdapter extends BaseAdapter implements PinnedSectionListAdapter {
      ...
      // We implement this method to return 'true' for all view types we want to pin
      @Override
      public boolean isItemViewTypePinned(int viewType) {
          return viewType == <type to be pinned>;
      }
}

 项目地址:https://github.com/beworker/pinned-section-listview


最后推荐一个demo:http://blog.csdn.net/anddroid_lanyan/article/details/41895631


相关文章
全志平台A40I GPIO操作:adb通过debugfs控制GPIO
全志平台A40I GPIO操作:adb通过debugfs控制GPIO
487 0
|
存储 缓存 物联网
uboot 启动流程详细分析参考
uboot 启动流程详细分析参考
1432 1
|
前端开发 JavaScript C++
打造卓越 QML 层级设计:从入门到精通(一)
打造卓越 QML 层级设计:从入门到精通
3303 1
|
缓存 Ubuntu JavaScript
踩坑记录:QML加载图片资源
踩坑记录:QML加载图片资源
1847 0
|
传感器 Linux
在Linux中使用libmodbus库进行Modbus RTU主从机通信
Modbus RTU是一种常见的工业通信协议,用于在自动化系统中传输数据。libmodbus是一个流行的C库,用于在Linux系统上实现Modbus通信。本文将介绍如何使用libmodbus库在Linux上创建Modbus RTU主从机通信的示例代码。
5936 0
|
SQL 关系型数据库 数据库
C语言与数据库:使用C语言操作SQLite等数据库。
C语言与数据库:使用C语言操作SQLite等数据库。
ly~
|
12月前
|
Ubuntu Linux C语言
SDL 图形库安装常见错误及解决方法
SDL(Simple DirectMedia Layer)图形库安装过程中可能会遇到编译错误、运行时错误、依赖库缺失等问题。本文总结了在 Linux 和 Windows 系统上常见的错误及解决方法,包括检查和安装依赖库、配置 SDL 子系统、处理 X11 错误等,帮助用户顺利完成 SDL 的安装和配置。
ly~
2090 8
|
Shell 开发工具 git
使用openwrt搭建编译环境,编译一个demo
使用openwrt搭建编译环境,编译一个demo
601 1
|
芯片 Windows
一文带你认识 CP210x 并安装驱动
一文带你认识 CP210x 并安装驱动
1445 0
|
数据处理 调度 开发者
QML多线程魔法:探索不同方法,提升性能
QML多线程魔法:探索不同方法,提升性能
1504 0