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.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. 优势

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

7. 总结

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/72149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

css基本功

为什么 ::first-letter 是伪元素&#xff1f; ::first-letter 的作用是选择并样式化元素的第一个字母&#xff0c;它创建了一个虚拟的元素来包裹这个字母&#xff0c;因此属于伪元素。 grid布局 案例一 <!DOCTYPE html> <html lang"zh-CN"><head&…

基于WebRTC技术的EasyRTC嵌入式音视频SDK:多平台兼容与性能优化

在当今数字化、智能化的时代背景下&#xff0c;实时音视频通信技术已成为众多领域不可或缺的关键技术。基于WebRTC技术的EasyRTC嵌入式音视频SDK&#xff0c;凭借其在ARM、Linux、Windows、安卓、iOS等多平台上的兼容性&#xff0c;为开发者提供了强大的工具&#xff0c;推动了…

【Pandas】pandas Series last_valid_index

Pandas2.2 Series Time Series-related 方法描述Series.asfreq(freq[, method, how, …])用于将时间序列数据转换为指定的频率Series.asof(where[, subset])用于返回时间序列中指定索引位置的最近一个非缺失值Series.shift([periods, freq, axis, …])用于将时间序列数据沿指…

批量将 Excel 文档中的图片提取到文件夹

前面我们介绍过如何批量删除 Excel 文档中的所有图片或者指定的图片&#xff0c;其中就需要用到批量提取 Excel 文档中图片的操作。我们如何才能够将 Excel 文档中的图片快速的提取出来呢&#xff1f;其实单个 Excel 文档中的图片提取到文件夹中是有多种方法可以完成的&#xf…

【氮化镓】开态GaN HEMTs中氧诱导Vth漂移的缺陷演化

2019年,中国工程物理研究院电子工程研究所的Rong Wang等人基于实验研究和第一性原理计算,研究了开启态偏置下AlGaN/GaN高电子迁移率晶体管(HEMTs)中氧诱导的阈值电压(Vth)漂移的缺陷演化机理。实验结果表明,在开启态应力作用下,T型栅AlGaN/GaN HEMT的Vth发生了明显的负…

谷粒商城:性能压测JVM堆区

目录 Kit Apache JMeter VisualVM 堆内存 jvm内存模型 垃圾回收&#xff08;Garbage Collection, GC&#xff09; 新对象分配内存 GC步骤 MinorGC 性能优化 影响因素 优化 nginx动静分离 优化三级分类获取 Jvm参数配置堆区 测试 Kit Apache JMeter 压力测试&…

STM32全系大阅兵(2)

接前一篇文章:STM32全系大阅兵(1) 本文内容参考: STM32家族系列的区别_stm32各个系列区别-CSDN博客 STM32--STM32 微控制器详解-CSDN博客

7、基于osg引擎实现读取vtk数据通过着色器实现简单体渲染(1)

1、顶点着色器代码 #version 110 /* GLSL 1.10需要显式声明精度 (OpenGL ES要求) */ #ifdef GL_ES precision highp float; #endif // 体数据采样步长 uniform float xStepSize,yStepSize,zStepSize; // 体数据纹理和颜色纹理 uniform sampler3D baseTexture; uniform sample…

基于Ollama平台部署的Qwen大模型实现聊天机器人

文章目录 基于Ollama平台部署的Qwen大模型实现聊天机器人1 概述2 技术栈2.1 开发技术2.2 环境 3 实现步骤3.1 环境搭建3.1.1 WSL配置及Ubuntu安装3.1.2 Ollama安装及模型部署 3.2 模块安装3.2.1 安装Streamlit 1.42.23.2.2 安装requests 2.32.33.2.3 安装ollama 0.4.7 3.3 后端…

用DasViewer的时候3Dtiles 转osgb 可以直接指定目标坐标系吗?

没有指定坐标系选项&#xff0c;可以转换后&#xff0c;再进行一次坐标系转换。 DasViewer是一款免费极速实景三维模型浏览器&#xff0c;采用多细节层次模型逐步自适应加载技术,让用户在极低的电脑配置下,也能流畅的加载较大规模实景三维模型,提供方便快捷的数据浏览操作。 目…

【MySQL】MySQL服务器——mysqld

1.MySQL服务器 是名为 mysqld 的数据库服务器程序&#xff0c;和“主机”&#xff08;host&#xff09;不一样是一个多线程的单进程管理对磁盘和内存中数据库的访问支持并发的客户端连接支持多个存储引擎&#xff0c;常见的存储引擎包括InnoDB、MyISAM、Memory、Archive支持事…

vue启动 localhost无法访问

1. localhost 和 127.0.0.1 虽然都指向本机&#xff0c;但它们有细微的区别&#xff1a; - localhost 是一个域名&#xff0c;需要通过 DNS 解析或本地 hosts 文件解析为 IP 地址 - 127.0.0.1 是直接的 IP 地址&#xff0c;不需要解析过程 2. 无法访问 localhost 的可…

爬虫案例十三js逆向模拟登录中大网校

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、网站分析二、代码 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; js 逆向模拟登录中大网校 提示&#xff1a;以下是本篇文章正文内…

Java IO 与文件系统:File 类与流操作详解

在 Java 编程中&#xff0c;IO&#xff08;输入输出&#xff09;操作是处理文件和数据流的核心部分。本文将围绕文件系统、硬盘存储、Java 的 File 类以及 InputStream 和 OutputStream 的使用进行详细总结&#xff0c;帮助读者全面掌握 Java IO 编程的核心知识。 一、IO、存储…

我与DeepSeek读《大型网站技术架构》(13)- 大型网站典型故障案例分析

文章目录 第13章 大型网站典型故障案例分析日志管理缺陷引发的故障高并发数据库访问问题锁机制滥用导致服务超时缓存运维不当引发的全站瘫痪流程不规范导致的线上事故编程习惯问题引发功能异常生产环境滥用问题其他典型问题总结 第13章 大型网站典型故障案例分析 本章通过九个…

Git与GitHub:它们是什么,有什么区别与联系?

1.Git是什么&#xff1f; Git 是一个开源的、分布式版本控制系统&#xff08;Version Control System, VCS&#xff09;&#xff0c;由 Linus Torvalds 于 2005 年开发&#xff0c;最初用于管理 Linux 内核的开发。它的核心功能是跟踪文件的变更历史&#xff0c;帮助开发者高效…

江科大51单片机笔记【12】AT24C02(I2C总线)

写在前言 此为博主自学江科大51单片机&#xff08;B站&#xff09;的笔记&#xff0c;方便后续重温知识 在后面的章节中&#xff0c;为了防止篇幅过长和易于查找&#xff0c;我把一个小节分成两部分来发&#xff0c;上章节主要是关于本节课的硬件介绍、电路图、原理图等理论知识…

ClickHouse SQL优化:从原理到实战的深度指南

目录 ​ClickHouse架构核心解析 1.1 列式存储的利刃与短板 1.2 MergeTree引擎的物理存储密码 1.3 向量化执行引擎的运算革命 ​数据建模的黄金法则 2.1 分区键设计的二十倍性能差异实验 2.2 主键排序的磁盘命中率法则 2.3 稀疏索引的数学选择策略 ​SQL优化十诫 3.1 查询模式反…

面试之《前端常见的设计模式》

前端开发中运用多种设计模式可以提高代码的可维护性、可扩展性和可复用性。以下是一些常见的前端设计模式&#xff1a; 创建型模式 1. 单例模式 定义&#xff1a;确保一个类只有一个实例&#xff0c;并提供一个全局访问点。应用场景&#xff1a;在前端中&#xff0c;像全局状…

Unity Android出包

Unity Android出包 1.Android Studio版本 不能高于Unity的版本 2.so库 这个库需要自己拷贝到Android工程当中 3.JDK版本太老 编译可以正常&#xff0c;但无法运行 File->ProjectStructure->SDK Location->Gradle Setting->Gradle JDK->X:/Android Stuido/jre …