实际上这个问题很多刷新框架都有,如果你正在用除XRefreshView的其他框架困扰,可以参考本文进行改造。
问题描述:比如我要做个新闻app,上面有n个新选项卡,我希望一切换该选项卡就刷新,如果正在下拉刷新则延长时间。刷新列表的界面各个选项卡公用。
问题来了,使用xrefreshview的时候,我切换选项卡它刷新了,但是刷新过程中继续切换,它不会重新刷新,两次下拉不会重新刷新。
那么,如果解决这个问题呢?
首先,什么时候会停止刷新?
调用:xRefreshView.stopRefresh();立刻停止刷新。
那么,就要有限制有判断的调用它了,于是,我再每次调用xRefreshView.startRefresh()的时候都使用变量记录它:
mXRefreshProductList.startRefresh();
++refreshTime;
调用stopRefresh前减少它:
--refreshTime;
if(refreshTime <= 0){
refreshTime = 0;
mXRefreshProductList.stopRefresh();
}
这样就保证了次数,但是还有问题,就是XRefreshView本身多次调用startRefresh内部不会重复调用onRefresh回调,导致刷新不停,于是改XRefreshView的startRefresh()源码:
if (!mEnablePullRefresh || mHolder.mOffsetY != 0 || mContentView.isLoading() || mPullRefreshing || !isEnabled()) {
return;
}
改为:
if (!mEnablePullRefresh || mHolder.mOffsetY != 0 || mContentView.isLoading() || mPullRefreshing || !isEnabled()) {
if(mHolder.mOffsetY != 0 && mPullRefreshing){
if (mRefreshViewListener != null) {
mRefreshViewListener.onRefresh();
mRefreshViewListener.onRefresh(false);
}
}
return;
}
切换时成功的能加载到最后一次了,但新的问题又来了,下拉刷新居然会失效。。。于是在回调onRefresh中改为:
loadData();
if(isPullDown){
refreshTime = 0;
xRefreshView.stopRefresh();
}else{
--refreshTime;
if(refreshTime <= 0){
refreshTime = 0;
xRefreshView.stopRefresh();
}
这样就解决了手动刷新,但是下拉刷新还会存在刷新不同步这种问题,继续改造下拉刷新。。。
查找源码中调用onRefresh(true)的只有一处,发现里面有一个废弃的onRelease方法,把它放开发现每次下拉都可监听到了,在此回调中写++refreshTime希望可释放完成刷新,但是失败。。。查找后,发现原因两个:
1.不是每次下拉刷新都有调用下拉刷新onRefresh(true)
2.有时候下拉太少不会进行刷新,造成白白加了,但是没有刷新所以一直显示刷新没有停止。
于是改造,改造前:
if (mHolder.mOffsetY != 0 && mRefreshViewListener != null
) {
mRefreshViewListener.onRelease(mHolder.mOffsetY);
}
if (mHolder.hasHeaderPullDown()) {
if (mEnablePullRefresh && !mStopingRefresh && !mPullRefreshing && mHolder.mOffsetY > mHeaderViewHeight) {
mPullRefreshing = true;
mHeaderCallBack.onStateRefreshing();
mState = XRefreshViewState.STATE_REFRESHING;
if (mRefreshViewListener != null) {
mRefreshViewListener.onRefresh();
mRefreshViewListener.onRefresh(true);
}
}
resetHeaderHeight();
}
解决问题1:
发现if (mEnablePullRefresh && !mStopingRefresh && !mPullRefreshing && mHolder.mOffsetY > mHeaderViewHeight) 这个判断有点问题,因为 !mStopingRefresh && !mPullRefreshing这两个条件是刷新过程中不会满足的,于是删掉,变为:
if (mEnablePullRefresh && mHolder.mOffsetY > mHeaderViewHeight) {}
这样,问题1解决。
解决问题2:
不成功时不会进入if (mEnablePullRefresh && mHolder.mOffsetY > mHeaderViewHeight),那么在else中加个回调,各种bug都加回调,添加这个返回方法,在里面–refreshTime.
改造后:
if (mHolder.hasHeaderPullDown()) {
if (mEnablePullRefresh && mHolder.mOffsetY > mHeaderViewHeight) {
mPullRefreshing = true;
mHeaderCallBack.onStateRefreshing();
mState = XRefreshViewState.STATE_REFRESHING;
if (mRefreshViewListener != null) {
mRefreshViewListener.onRefresh();
mRefreshViewListener.onRefresh(true);
}
}else{
mRefreshViewListener.refreshFailed();
}
resetHeaderHeight();
}
回调:
@Override
public void refreshFailed() {
super.refreshFailed();
--refreshTime;
}
最后改一下刷新的onRefresh():
loadData();
--refreshTime;
if(refreshTime <= 0){
refreshTime = 0;
xRefreshView.stopRefresh();
这样终于不论切换多少次选项卡,有下拉多少次都会自动刷新了。
当然,可以更优,你可以在加载前取消之前的网络请求,这样能有效减少流量,加快加载速度,避免多次加载,这些因为公司项目原因不写了,不过读者最好还是思考一下。