很多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.
}