RecyclerView 實現下拉刷新和自動加載

魔鬼旋律 8年前發布 | 33K 次閱讀 Android開發 移動開發 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 流程圖

參考文獻

 本文由用戶 魔鬼旋律 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!