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


相关文章
|
9月前
|
索引
RecyclerView,ListView实现顶部悬浮、字母排序、过滤搜索
RecyclerView,ListView实现顶部悬浮、字母排序、过滤搜索
92 0
|
前端开发 Android开发 iOS开发
Andorid分组Item顶部悬停 + 交互同步
  项目中某些页面中的分组数据的顶部需要悬停,并且悬停的View要与ItemView中同样布局的View进行操作同步,也就是相互同步。大家都知道,Android中有"The specified child already has a parent. You must call removeView() on the child's parent first."这个异常,意味着同一个View对象不能有两个Parent。我们就不能简单粗暴的将同一个View对象添加进两个parent了,需要另谋出路。
|
C# 索引
C# 获取listview中选中一行的值
C# 获取listview中选中一行的值
707 0
SwiftUI—使用ScrollView在限定的区域显示超长的内容
SwiftUI—使用ScrollView在限定的区域显示超长的内容
343 0
SwiftUI—使用ScrollView在限定的区域显示超长的内容
|
JavaScript
使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态。点击列表的项,切换二级列表的显示或隐藏状态
使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态。点击列表的项,切换二级列表的显示或隐藏状态
388 0
使用jQuery 中的显示与隐藏动画效果实现折叠下拉菜单的收缩和展开,在页面的列表中有若干项,列表的每项中有一个二级列表,二级列表默认为隐藏状态。点击列表的项,切换二级列表的显示或隐藏状态
|
容器
左侧固定,右侧自适应的布局方式(新增评论区大佬教的方法)
一.浮动布局 1.先让固定宽度的div浮动!使其脱离文档流。 2.margin-left的值等于固定div的宽度相等。 .
808 0
HorizontalScrollView包裹RecyclerView,使用StaggeredGridLayoutManager均分网格形成表格状列表,不固定列,每次刷新数据列位置异常错乱变动问题
HorizontalScrollView包裹RecyclerView,使用StaggeredGridLayoutManager均分网格形成表格状列表,不固定列,每次刷新数据列位置异常错乱变动问题 问题描述:用Horizon...
1943 0
|
前端开发
固定滚动菜单
<!DOCTYPE html> <html> <head>     <meta charset="utf-8"/>     <title>test</title>          <style type="text/css">         *{ margin:0; padding:0;}         .
739 0
|
XML Android开发 数据格式
Android开发技巧——使用RecyclerView实现分组列表
有一个多月没写原创博客了,今天来介绍一下使用RecyclerView来实现分组列表。之所以使用RecyclerView,主要原因还是因为项目开发中使用ExpandableListView无法实现设计师所需要的分割线。
3177 0
|
前端开发 Android开发 网络架构
类似通讯录分组的Android PinnedSectionListView,且分组标签悬停滑入滑出
 《类似通讯录分组的Android PinnedSectionListView,且分组标签悬停滑入滑出》 常用的联系人、通讯录,会按照联系人的姓氏从A,B,C,,,X,Y,Z,这样归类排列下去,方便用户快速查找和定位。
791 0