標籤:
很多android應用的下拉重新整理都是使用的pulltorefresh這個開源項目,但是它的擴充性在下拉重新整理同時又上拉載入更多時會有一定的局限性。查了很多地方,發現這個開源項目並不能很好的同時支援下拉重新整理和上拉載入更多。這個組件有個mode的屬性,可以設定為both,即上下同時都可拉動。但是只設定這個屬性的話,上拉與下拉產生的效果是完全一致的。所以要使用這個開源項目做到下拉重新整理並同時可上拉載入更多,就需要在代碼中進行一些處理。
==========================pulltorefresh屬性相關=====================================
開源項目: Android-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; |
setOnRefreshListener(OnRefreshListener listener):設定重新整理監聽器;
setOnLastItemVisibleListener(OnLastItemVisibleListener listener):設定是否到底部監聽器;
setOnPullEventListener(OnPullEventListener listener);設定事件監聽器;
onRefreshComplete():設定重新整理完成
========================== 監聽listview滾動方向=====================================
修改為上拉載入更多的關鍵在於onrefresh方法執行之前判斷出listview的滾動方向。以下方法是所嘗試的方法中效果最好的一種,並不能說完美解決,但應該是效果最接近的一種了。(當首屏資料行數未充滿螢幕,或者滾動時第一行的滾動距離小於行高,可能還是會存在一點誤差。不過大部分應用的列表每頁資料一般都能充滿螢幕,也可在此基礎結合其他手勢判斷對此方法進行改善)。
int mLastFirstVisibleItem = 0;boolean mIsScrollingUp;@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState){ if (view.getId() == mListView.getId()) { final int currentFirstVisibleItem = mListView.getFirstVisiblePosition(); if (currentFirstVisibleItem > mLastFirstVisibleItem) { mIsUp = true; } else if (currentFirstVisibleItem < mLastFirstVisibleItem) { mIsUp = false; } mLastFirstVisibleItem = currentFirstVisibleItem; } }
參考資料:http://stackoverflow.com/questions/12114963/detecting-the-scrolling-direction-in-the-adapter-up-down/12115157#12115157
========================== 實現下拉重新整理和上拉載入更多====================================
解析json完畢後,判斷是上拉操作還是下拉重新整理操作:
// 解析jsonprivate void parseJson(String result){ List<ListJson> localList = parseJsonArray(Utils.parseListJson(result, "key")); if(!mIsUp) { mDataList.clear(); } mDataList.addAll(localList);}
資料載入完畢後,notifyDataSetChanged和通知PullRefreshListView,同時頁碼加1:
// 載入完畢處理private void loadComplete(){ mPullRefreshListView.onRefreshComplete(); mAdapter.notifyDataSetChanged(); mPage += 1;}
判斷上拉和下拉方向,監聽重新整理listview,修改頭部和底部view的文字說明:
/** * *******************下拉重新整理與上拉載入的監聽處理************************ */// 重新整理listview監聽@Overridepublic void onRefresh(PullToRefreshBase<ListView> refreshView){ // 擷取重新整理時間,設定重新整理時間格式 String str = DateUtils.formatDateTime(getActivity(), System.currentTimeMillis(), DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_NO_NOON); // 判斷下拉還是上拉 if (!mIsUp) mPage = 0; // 設定重新整理文本說明(重新整理過程中) if (mIsUp) { mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在載入"); mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉載入更多"); mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("釋放開始載入"); refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最後載入時間:" + str); } else { mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在重新整理"); mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉重新整理"); mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("釋放開始重新整理"); refreshView.getLoadingLayoutProxy().setLastUpdatedLabel("最後更新時間:" + str); } // 啟動下載任務,載入資料 loadTask();}int mLastFirstVisibleItem = 0;boolean mIsScrollingUp;@Overridepublic void onScrollStateChanged(AbsListView view, int scrollState){ if (view.getId() == mListView.getId()) { final int currentFirstVisibleItem = mListView.getFirstVisiblePosition(); if (currentFirstVisibleItem > mLastFirstVisibleItem) { mIsUp = true; } else if (currentFirstVisibleItem < mLastFirstVisibleItem) { mIsUp = false; } mLastFirstVisibleItem = currentFirstVisibleItem; } }@Overridepublic void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount){ // 設定重新整理文本說明(展開重新整理欄前) if (mIsUp) { mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在載入"); mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("上拉載入更多"); mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("釋放開始載入"); } else { mPullRefreshListView.getLoadingLayoutProxy().setRefreshingLabel("正在重新整理"); mPullRefreshListView.getLoadingLayoutProxy().setPullLabel("下拉重新整理"); mPullRefreshListView.getLoadingLayoutProxy().setReleaseLabel("釋放開始重新整理"); } }@Overridepublic void onLastItemVisible(){ mIsUp = true;}
/////////////////////////////////////////////////////////////////////////////////////////
lvVideo.setOnScrollListener(new OnScrollListener() {
@Override
public void onScrollStateChanged(AbsListView view, int scrollState) {
switch (scrollState) {
// 滾動之前,手還在螢幕上 記錄滾動前的下標
case OnScrollListener.SCROLL_STATE_TOUCH_SCROLL:
//view.getLastVisiblePosition()得到當前螢幕可見的第一個item在整個listview中的下標
lvIndext=view.getLastVisiblePosition();
break;
//滾動停止
case OnScrollListener.SCROLL_STATE_IDLE:
//記錄滾動停止後 記錄當前item的位置
int scrolled=view.getLastVisiblePosition();
//滾動後下標大於滾動前 向下滾動了
if(scrolled>lvIndext){
//scroll = false;
UIHelper.ToastMessage(VideoMain.this,"菜單收合");
}
//向上滾動了
else{
UIHelper.ToastMessage(VideoMain.this,"菜單彈出");
//scroll = true;
}
break;
//////////////////////////////////////////////////////////////////////////////////////////////////////
OnScrollListener 的 onScroll() 有一個 firstVisibleItem 參數(第二個參數),向下滑動會越來越大,向上滑動就會越來越小,可以在滑動的時候儲存一下這個值,然後再與當前值進行判斷
另外也可以通過view.getLastVisiblePosition() 判斷,這個返回的則是螢幕底部。
Android項目:使用pulltorefresh開源項目擴充為下拉重新整理上拉載入更多的處理方法,監聽listview滾動方向