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:https://blog.csdn.net/anddroid_lanyan/article/details/41895631
最後更新:2017-04-03 12:55:32