当前位置: 首页 > article >正文

Android 列表页面终极封装:SmartRefreshLayout + BRVAH 实现下拉刷新和加载更多

在 Android 开发中,列表页面是常见的 UI 设计模式,而下拉刷新和加载更多是提升用户体验的关键功能。本文将带你从零开始,封装一个高复用性的 SmartRefreshHelper 工具类,结合 SmartRefreshLayoutBRVAH,实现高效、灵活的列表页面。你将学到:

  • 如何封装 SmartRefreshHelper 工具类,简化列表页面的实现。
  • 支持下拉刷新、加载更多、空布局和加载更多失败处理。
  • 通过代码示例和布局文件,快速上手并应用到实际项目中。

包括 SmartRefreshLayoutBRVAH 的封装下拉刷新和加载更多功能空布局支持加载更多失败处理 以及 网络请求封装。所有内容都经过优化,确保代码简洁、高效且易于扩展。


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.SmartRefreshLayout
    xmlns: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.RecyclerView
        android: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">

    <TextView
        android: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">

    <TextView
        android: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;

        // 初始化 RecyclerView
        recyclerView.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>() {
            @Override
            public void onSuccess(List<T> data) {
                if (isRefresh) {
                    adapter.setList(data); // 刷新数据
                    refreshLayout.finishRefresh(); // 结束刷新
                } else {
                    adapter.addData(data); // 添加更多数据
                    refreshLayout.finishLoadMore(); // 结束加载更多
                }
            }

            @Override
            public 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);
    }

    @Override
    protected 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;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // 初始化适配器
        MyAdapter adapter = new MyAdapter(new ArrayList<>());

        // 初始化 SmartRefreshHelper
        smartRefreshHelper = new SmartRefreshHelper<>(
                this,
                R.id.refreshLayout,
                R.id.recyclerView,
                adapter,
                new SmartRefreshHelper.DataLoader<String>() {
                    @Override
                    public 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. 优势

  1. 空布局支持:当数据为空时显示提示。
  2. 加载更多失败处理:提升用户体验。
  3. 网络请求封装:通过 DataLoader 接口解耦网络请求逻辑。
  4. 代码复用性优化:通过泛型支持多种数据类型。
  5. 简洁高效:逻辑清晰,易于维护和扩展。

7. 总结

通过优化后的 SmartRefreshHelper,我们实现了一个功能强大且灵活的列表页面,支持下拉刷新、加载更多、空布局和加载更多失败处理。这种封装方式不仅提高了代码的复用性,还简化了开发流程。

核心功能
  • 下拉刷新:重置数据并加载第一页。
  • 加载更多:追加数据并加载下一页。
  • 空布局:当数据为空时显示提示。
  • 加载更多失败处理:提升用户体验。
扩展功能
  • 自定义刷新头和加载更多:满足个性化需求。
  • 支持多种数据类型:通过泛型实现。

http://www.kler.cn/a/582498.html

相关文章:

  • 无广告记账助手:个人小企业财务管理
  • 02.Kubernetes 集群部署
  • UE5.4分层渲染设置
  • 神经网络机器学习中说的过拟合是什么意思
  • Spring Boot + InfluxDB 实现高效数据存储与查询
  • 【实战-解决方案】Webpack 打包后很多js方法报错:not defined
  • 关于MCP SSE 服务器的工作原理
  • Kotlin D3
  • Vite项目中vite.config.js中为什么只能使用process.env,无法使用import.meta.env?
  • 使用expect工具实现远程批量修改服务器密码
  • Mac 如何在idea集成SVN
  • CSS整理学习合集(2)
  • 从异步讲到回调函数
  • 开启AI开发新时代——全解析Dify开源LLM应用开发平台
  • 大模型叙事下的百度智能云:比创新更重要的,是创新的扩散
  • NineData:解锁多云与混合云环境下的智能数据管理
  • (三)Dart 变量
  • 后端 - java - - 重写与重载的区别
  • mock的定义和使用场景
  • 程序代码篇---STM舵机控制