github源码分享PinnedSectionListView:分组的listView滑动中固定组标题的实现

泡在网上的日子 / 文 发表于2014-03-07 00:02 次阅读 listview,github,android

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

先看截图:

   



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

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

@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

<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。

// 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


收藏 赞 (2) 踩 (2)
上一篇:详解android绘制动画效果的曲线图的实现
安卓绘制统计图可以用 androidchart ,也可以自己绘制,不像 ios , android 能找到的开源库在 UI 方面都很差,要做出吸引人地方还是需要自己绘制。 本文给出最常用的曲线图的绘制方法。 绘制曲线图首先需要画好横竖坐标轴建立坐标系,比如坐标系中的 100 距
下一篇:自定义带动画效果的矩形条控件
项目的原因需要一个带动画效果的矩形条,因为progressbar需要设置主题(有些主题下为圆圈)而且没有自带动画,所以自己写了个控件。 下面是实现方法: 1.继承自View public class SingleBarChart extends View 2.成员变量 private Paint mPaint;private int