閱讀866 返回首頁    go 阿裏雲 go 技術社區[雲棲]


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) {
         returnviewType == <type to be pinned>;
     }
}

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


最後推薦一個demo:https://blog.csdn.net/anddroid_lanyan/article/details/41895631


最後更新:2017-04-03 12:55:32

  上一篇:go 2011藍橋杯【初賽試題】程序設計題一
  下一篇:go 準備將博客從CSDN搬家http://www.fenesky.com