PinnedSectionListView:分組的listView滑動中固定組標題的實現
在很多應用中,看到這樣的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