在 Android 開發中,列表頁面是常見的 UI 設計模式,而下拉刷新和加載更多是提升用戶體驗的關鍵功能。本文將帶你從零開始,封裝一個高復用性的 SmartRefreshHelper
工具類,結合 SmartRefreshLayout
和 BRVAH
,實現高效、靈活的列表頁面。你將學到:
- 如何封裝
SmartRefreshHelper
工具類,簡化列表頁面的實現。 - 支持下拉刷新、加載更多、空布局和加載更多失敗處理。
- 通過代碼示例和布局文件,快速上手并應用到實際項目中。
包括 SmartRefreshLayout
和 BRVAH
的封裝、下拉刷新和加載更多功能、空布局支持、加載更多失敗處理 以及 網絡請求封裝。所有內容都經過優化,確保代碼簡潔、高效且易于擴展。
1. 添加依賴
在 build.gradle
中添加以下依賴:
dependencies {// SmartRefreshLayout 下拉刷新和加載更多implementation 'io.github.scwang90:refresh-layout-kernel:2.0.6' // 核心庫implementation 'io.github.scwang90:refresh-header-classics:2.0.6' // 經典刷新頭implementation 'io.github.scwang90:refresh-footer-classics:2.0.6' // 經典加載更多// BRVAH 高效適配器implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:3.0.14'
}
2. 布局文件
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<com.scwang.smart.refresh.layout.SmartRefreshLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/refreshLayout"android:layout_width="match_parent"android:layout_height="match_parent"><!-- RecyclerView --><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/recyclerView"android:layout_width="match_parent"android:layout_height="match_parent"/></com.scwang.smart.refresh.layout.SmartRefreshLayout>
item_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="wrap_content"android:orientation="vertical"android:padding="16dp"><TextViewandroid:id="@+id/textView"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Item"android:textSize="18sp"/>
</LinearLayout>
empty_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:gravity="center"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="No data available"android:textSize="18sp"/>
</LinearLayout>
3. 封裝 SmartRefreshHelper 工具類
import android.app.Activity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.scwang.smart.refresh.layout.api.RefreshLayout;
import com.scwang.smart.refresh.layout.listener.OnLoadMoreListener;
import com.scwang.smart.refresh.layout.listener.OnRefreshListener;
import java.util.List;/*** 封裝 SmartRefreshLayout 和 BRVAH 的工具類* 功能:支持下拉刷新、加載更多、空布局和加載更多失敗處理*/
public class SmartRefreshHelper<T> {private final Activity activity;private final RefreshLayout refreshLayout;private final RecyclerView recyclerView;private final BaseQuickAdapter<T, ?> adapter;private final DataLoader<T> dataLoader;private int page = 1; // 當前頁碼/*** 構造函數** @param activity Activity 實例* @param refreshLayoutId SmartRefreshLayout 的 ID* @param recyclerViewId RecyclerView 的 ID* @param adapter 數據適配器* @param dataLoader 數據加載器*/public SmartRefreshHelper(Activity activity, int refreshLayoutId, int recyclerViewId,BaseQuickAdapter<T, ?> adapter, DataLoader<T> dataLoader) {this.activity = activity;this.refreshLayout = activity.findViewById(refreshLayoutId);this.recyclerView = activity.findViewById(recyclerViewId);this.adapter = adapter;this.dataLoader = dataLoader;// 初始化 RecyclerViewrecyclerView.setLayoutManager(new LinearLayoutManager(activity));recyclerView.setAdapter(adapter);// 設置下拉刷新和加載更多監聽器initRefreshListener();}/*** 初始化下拉刷新和加載更多監聽器*/private void initRefreshListener() {// 下拉刷新refreshLayout.setOnRefreshListener((RefreshLayout refreshLayout) -> {page = 1; // 重置頁碼loadData(page, true); // 加載第一頁數據});// 加載更多refreshLayout.setOnLoadMoreListener((RefreshLayout refreshLayout) -> {page++; // 加載下一頁loadData(page, false);});}/*** 加載數據** @param page 當前頁碼* @param isRefresh 是否是刷新操作*/private void loadData(int page, boolean isRefresh) {dataLoader.loadData(page, new DataLoader.Callback<T>() {@Overridepublic void onSuccess(List<T> data) {if (isRefresh) {adapter.setList(data); // 刷新數據refreshLayout.finishRefresh(); // 結束刷新} else {adapter.addData(data); // 添加更多數據refreshLayout.finishLoadMore(); // 結束加載更多}}@Overridepublic void onFailure(String message) {if (isRefresh) {refreshLayout.finishRefresh(false); // 刷新失敗} else {refreshLayout.finishLoadMore(false); // 加載更多失敗}}});}/*** 設置空布局** @param emptyLayoutId 空布局的資源 ID*/public void setEmptyView(int emptyLayoutId) {adapter.setEmptyView(emptyLayoutId);}/*** 數據加載器接口*/public interface DataLoader<T> {void loadData(int page, Callback<T> callback);interface Callback<T> {void onSuccess(List<T> data);void onFailure(String message);}}
}
4. 適配器實現
MyAdapter
import com.chad.library.adapter.base.BaseQuickAdapter;
import com.chad.library.adapter.base.viewholder.BaseViewHolder;
import java.util.List;public class MyAdapter extends BaseQuickAdapter<String, BaseViewHolder> {public MyAdapter(List<String> data) {super(R.layout.item_layout, data);}@Overrideprotected void convert(@NonNull BaseViewHolder holder, String item) {// 綁定數據到視圖holder.setText(R.id.textView, item);}
}
5. 在 Activity 中使用
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import java.util.ArrayList;
import java.util.List;public class MainActivity extends AppCompatActivity {private SmartRefreshHelper<String> smartRefreshHelper;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 初始化適配器MyAdapter adapter = new MyAdapter(new ArrayList<>());// 初始化 SmartRefreshHelpersmartRefreshHelper = new SmartRefreshHelper<>(this,R.id.refreshLayout,R.id.recyclerView,adapter,new SmartRefreshHelper.DataLoader<String>() {@Overridepublic void loadData(int page, SmartRefreshHelper.DataLoader.Callback<String> callback) {// 模擬網絡請求new Handler().postDelayed(() -> {List<String> data = getData(page); // 獲取數據if (data.isEmpty()) {callback.onFailure("No more data"); // 加載失敗} else {callback.onSuccess(data); // 加載成功}}, 2000); // 2秒延遲}});// 設置空布局smartRefreshHelper.setEmptyView(R.layout.empty_layout);// 首次加載數據smartRefreshHelper.loadData(1, true);}/*** 模擬獲取數據** @param page 當前頁碼* @return 數據列表*/private List<String> getData(int page) {List<String> data = new ArrayList<>();for (int i = 0; i < 10; i++) {data.add("Item " + (page * 10 + i));}return data;}
}
6. 優勢
- 空布局支持:當數據為空時顯示提示。
- 加載更多失敗處理:提升用戶體驗。
- 網絡請求封裝:通過
DataLoader
接口解耦網絡請求邏輯。 - 代碼復用性優化:通過泛型支持多種數據類型。
- 簡潔高效:邏輯清晰,易于維護和擴展。
7. 總結
通過優化后的 SmartRefreshHelper
,我們實現了一個功能強大且靈活的列表頁面,支持下拉刷新、加載更多、空布局和加載更多失敗處理。這種封裝方式不僅提高了代碼的復用性,還簡化了開發流程。
核心功能
- 下拉刷新:重置數據并加載第一頁。
- 加載更多:追加數據并加載下一頁。
- 空布局:當數據為空時顯示提示。
- 加載更多失敗處理:提升用戶體驗。
擴展功能
- 自定義刷新頭和加載更多:滿足個性化需求。
- 支持多種數據類型:通過泛型實現。