很多android應用的下拉刷新都是使用的pulltorefresh這個開源項目,但是它的擴展性在下拉刷新同時又上拉加載更多時會有一定的侷限性。查了很多地方,發現這個開源項目並不能很好的同時支持下拉刷新和上拉加載更多。這個組件有個mode的屬性,可以設置爲both,即上下同時都可拉動。但是隻設置這個屬性的話,上拉與下拉產生的效果是完全一致的。所以要使用這個開源項目做到下拉刷新並同時可上拉加載更多,就需要在代碼中進行一些處理。
==========================pulltorefresh屬性相關=====================================
項目地址:https://github.com/chrisbanes/Android-PullToRefresh/wiki/Quick-Start-Guide
1.屬性:https://github.com/chrisbanes/Android-PullToRefresh/blob/master/library/res/values/attrs.xml
命名空間: xmlns:ptr="http://schemas.android.com/apk/res-auto"
ptr:ptrAnimationStyle | 動畫效果 提供了兩個值 flip和rotate 默認爲rotate |
ptr:ptrRefreshableViewBackground | 設置刷新View的背景顏色 |
ptr:ptrHeaderBackground | 設置頭部View的背景顏色 |
ptr:ptrHeaderTextColor | 設置頭部View文字的顏色 |
ptr:ptrHeaderSubTextColor | 設置頭部view副標題文字的顏色 |
ptr:ptrMode |
pullFromStart: pullFromEnd: both; |
2.常用方法
setOnRefreshListener(OnRefreshListener listener):設置刷新監聽器;
setOnLastItemVisibleListener(OnLastItemVisibleListener listener):設置是否到底部監聽器;
setOnPullEventListener(OnPullEventListener listener);設置事件監聽器;
onRefreshComplete():設置刷新完成
==========================監聽listview滾動方向=====================================
修改爲上拉加載更多的關鍵在於onrefresh方法執行之前判斷出listview的滾動方向。以下方法是所嘗試的方法中效果最好的一種,並不能說完美解決,但應該是效果最接近的一種了。(當首屏數據行數未充滿屏幕,或者滾動時第一行的滾動距離小於行高,可能還是會存在一點誤差。不過大部分應用的列表每頁數據一般都能充滿屏幕,也可在此基礎結合其他手勢判斷對此方法進行改善)。
01.
int
mLastFirstVisibleItem
= 0;
02.
boolean
mIsScrollingUp;
03.
@Override
04.
public
void
onScrollStateChanged(AbsListView
view,
int
scrollState)
05.
{
06.
07.
if
(view.getId()
== mListView.getId())
08.
{
09.
final
int
currentFirstVisibleItem
= mListView.getFirstVisiblePosition();
10.
11.
if
(currentFirstVisibleItem
> mLastFirstVisibleItem)
12.
{
13.
mIsUp
=
true
;
14.
}
15.
else
if
(currentFirstVisibleItem
< mLastFirstVisibleItem)
16.
{
17.
mIsUp
=
false
;
18.
}
19.
mLastFirstVisibleItem
= currentFirstVisibleItem;
20.
}
21.
22.
}
參考資料:http://stackoverflow.com/questions/12114963/detecting-the-scrolling-direction-in-the-adapter-up-down/12115157#12115157
==========================實現下拉刷新和上拉加載更多====================================
解析json完畢後,判斷是上拉操作還是下拉刷新操作:
01.
//
解析json
02.
private
void
parseJson(String
result)
03.
{
04.
List<ListJson>
localList = parseJsonArray(Utils.parseListJson(result,
"key"
));
05.
06.
if
(!mIsUp)
07.
{
08.
mDataList.clear();
09.
}
10.
mDataList.addAll(localList);
11.
}
數據加載完畢後,notifyDataSetChanged和通知PullRefreshListView,同時頁碼加1:
1.
//
加載完畢處理
2.
private
void
loadComplete()
3.
{
4.
mPullRefreshListView.onRefreshComplete();
5.
mAdapter.notifyDataSetChanged();
6.
mPage
+=
1
;
7.
}
判斷上拉和下拉方向,監聽刷新listview,修改頭部和底部view的文字說明:
01.
/**
02.
*
*******************下拉刷新與上拉加載的監聽處理************************
03.
*/
04.
//
刷新listview監聽
05.
@Override
06.
public
void
onRefresh(PullToRefreshBase<ListView>
refreshView)
07.
{
08.
//
獲取刷新時間,設置刷新時間格式
09.
String
str = DateUtils.formatDateTime(getActivity(), System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON);
10.
11.
//
判斷下拉還是上拉
12.
if
(!mIsUp)
13.
mPage
= 0;
14.
15.
//
設置刷新文本說明(刷新過程中)
16.
if
(mIsUp)
17.
{
18.
mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel(
"正在加載"
);
19.
mPullRefreshListView.getLoadingLayoutProxy().setPullLabel(
"上拉加載更多"
);
20.
mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel(
"釋放開始加載"
);
21.
refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(
"最後加載時間:"
+
str);
22.
}
23.
else
24.
{
25.
mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel(
"正在刷新"
);
26.
mPullRefreshListView.getLoadingLayoutProxy().setPullLabel(
"下拉刷新"
);
27.
mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel(
"釋放開始刷新"
);
28.
refreshView.getLoadingLayoutProxy().setLastUpdatedLabel(
"最後更新時間:"
+
str);
29.
}
30.
31.
//
啓動下載任務,加載數據
32.
loadTask();
33.
}
34.
int
mLastFirstVisibleItem
= 0;
35.
boolean
mIsScrollingUp;
36.
@Override
37.
public
void
onScrollStateChanged(AbsListView
view,
int
scrollState)
38.
{
39.
40.
if
(view.getId()
== mListView.getId())
41.
{
42.
final
int
currentFirstVisibleItem
= mListView.getFirstVisiblePosition();
43.
44.
if
(currentFirstVisibleItem
> mLastFirstVisibleItem)
45.
{
46.
mIsUp
=
true
;
47.
}
48.
else
if
(currentFirstVisibleItem
< mLastFirstVisibleItem)
49.
{
50.
mIsUp
=
false
;
51.
}
52.
mLastFirstVisibleItem
= currentFirstVisibleItem;
53.
}
54.
55.
}
56.
@Override
57.
public
void
onScroll(AbsListView
view,
int
firstVisibleItem,
int
visibleItemCount,
int
totalItemCount)
58.
{
59.
//
設置刷新文本說明(展開刷新欄前)
60.
if
(mIsUp)
61.
{
62.
mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel(
"正在加載"
);
63.
mPullRefreshListView.getLoadingLayoutProxy().setPullLabel(
"上拉加載更多"
);
64.
mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel(
"釋放開始加載"
);
65.
}
66.
else
67.
{
68.
mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel(
"正在刷新"
);
69.
mPullRefreshListView.getLoadingLayoutProxy().setPullLabel(
"下拉刷新"
);
70.
mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel(
"釋放開始刷新"
);
71.
}
72.
73.
}
74.
@Override
75.
public
void
onLastItemVisible()
76.
{
77.
mIsUp
=
true
;
78.
}