RecyclerView 實現下拉刷新和自動加載
來自: http://android.jobbole.com/82442/
RecyclerView是 Android 兼容包V21中新推出的列表類,它的自定義化強的優點足以讓它能夠取代GridView和ListView,本文將結合SwipeRefreshLayout與RecyclerView講解如何實現下拉刷新和自動加載的代碼
需要的依賴
以下版本自行更新
Java
compile 'com.android.support:appcompat-v7:21.0.0' compile 'com.android.support:recyclerview-v7:21.0.0' compile 'com.android.support:cardview-v7:21.0.0' compile 'com.android.support:support-v4:21.0.0'
compile 'com.android.support:appcompat-v7:21.0.0' compile 'com.android.support:recyclerview-v7:21.0.0' compile 'com.android.support:cardview-v7:21.0.0' compile 'com.android.support:support-v4:21.0.0'</div>
需要解決的問題
- [x] 下拉刷新
- [x] 自動加載
- [x] 網絡請求異步加載
技術處理
下拉刷新
采用 android.support.v4.widget.SwipeRefreshLayout 來實現
具體可以搜索這個class,我們按照官方文檔,布局如下
Java
<view xmlns:android="<view xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recylerView" class="android.support.v7.widget.RecyclerView" android:layout_width="wrap_content" android:layout_height="wrap_content"></view>
</view></pre>
<viewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/swipeRefreshLayout" class="android.support.v4.widget.SwipeRefreshLayout" android:layout_width="match_parent" android:layout_height="match_parent"> <viewxmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/recylerView" class="android.support.v7.widget.RecyclerView" android:layout_width="wrap_content" android:layout_height="wrap_content"></view> </view></div>然后對 swipeRefreshLayout 設置監聽即可
Java
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { if(isrefreshing){ Log.d(TAG,"ignore manually update!"); } else{ loadPage(); } } });swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() { @Override public void onRefresh() { if(isrefreshing){ Log.d(TAG,"ignore manually update!"); } else{ loadPage(); } } });</div>自動加載
RecyclerView是一個新興事物,伸手黨們還找不到 endless-RecyclerView 這樣的開源神器,只好自己找方法了,同ListView一樣,還是重寫 OnScrollListener 這個方法
Java
recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int lastVisibleItem = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition(); int totalItemCount = mLayoutManager.getItemCount(); //lastVisibleItem >= totalItemCount - 4 表示剩下4個item自動加載,各位自由選擇 // dy>0 表示向下滑動 if (lastVisibleItem >= totalItemCount - 4 && dy > 0) { if(isLoadingMore){ Log.d(TAG,"ignore manually update!"); } else{ loadPage();//這里多線程也要手動控制isLoadingMore isLoadingMore = false; } } } });recyclerView.setOnScrollListener(new RecyclerView.OnScrollListener() { @Override public void onScrolled(RecyclerViewrecyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int lastVisibleItem = ((LinearLayoutManager) mLayoutManager).findLastVisibleItemPosition(); int totalItemCount = mLayoutManager.getItemCount(); //lastVisibleItem >= totalItemCount - 4 表示剩下4個item自動加載,各位自由選擇 // dy>0 表示向下滑動 if (lastVisibleItem >= totalItemCount - 4 && dy > 0) { if(isLoadingMore){ Log.d(TAG,"ignore manually update!"); } else{ loadPage();//這里多線程也要手動控制isLoadingMore isLoadingMore = false; } } } });</div>如果想用GridView,可以試試這個,注意例子里的span_count =2
Java
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int[] visibleItems = mLayoutManager.findLastVisibleItemPositions(null); int lastitem = Math.max(visibleItems[0],visibleItems[1]); Log.d(TAG,"visibleItems =" + visibleItems); Log.d(TAG,"lastitem =" + lastitem); Log.d(TAG,"adapter.getItemCount() =" + adapter.getItemCount()); if (dy > 0 && lastitem > adapter.getItemCount() - 5 && !isLoadingMore) { Log.d(TAG,"will loadNewFeeds"); } }@Override public void onScrolled(RecyclerViewrecyclerView, int dx, int dy) { super.onScrolled(recyclerView, dx, dy); int[] visibleItems = mLayoutManager.findLastVisibleItemPositions(null); int lastitem = Math.max(visibleItems[0],visibleItems[1]); Log.d(TAG,"visibleItems =" + visibleItems); Log.d(TAG,"lastitem =" + lastitem); Log.d(TAG,"adapter.getItemCount() =" + adapter.getItemCount()); if (dy > 0 && lastitem > adapter.getItemCount() - 5 && !isLoadingMore) { Log.d(TAG,"will loadNewFeeds"); } }</div>網絡請求異步加載
我這里的 loadPage 是基于 Retrofit 構建的,輸入參數是一個Map,它的回調功能非常實用,可以直接控制UI更新,流程圖如下,大家可以參考一下設計
![]()
loadPage 流程圖
參考文獻
- 俄國佬代碼
- ListView祖傳代碼
</ul> </div>
本文由用戶 魔鬼旋律 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!相關經驗