XRecyclerview用法以及遇到的一些问题

2023-10-23 14:38

本文主要是介绍XRecyclerview用法以及遇到的一些问题,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近使用XRecyclerview来实现数据的刷新和上拉加载更多操作,由于第一次使用,踩了不少坑,本文即为记录问题.

概述

XRecyclerview的基本用法就不多说了,github上面介绍的比较清楚,也可以查看作者提供的example来方便了解用法,github地址:XRecyclerview
本文要说明的主要是使用XRecyclerview实现后台数据的下拉刷新以及上拉加载更多的实战,作者提供的demo里面是静态放置的数据,相对于简单,真正对接后台数据时可能会有很多未知问题,本文主要扒扒自己项目中遇到的坑和数据刷新加载的具体实现方式.

用法思路

实现思路:目前通过xrecyclerview的开源代码来实现系列功能,加载数据传入type,值为1,2,3,分别表示初次加载,下拉刷新数据,上拉加载更多数据操作,刷新数据只需要重新放入数据,然后notifyDataSetChanged();即可.加载更多数据只需要在上拉时将获取数据放入之前数据list中刷新数据即可.这么说可能会比较抽象,让我们通过代码来具体看看怎么实现的吧.

核心代码:
  • 首先需要配置xRecyclerview的属性:
xRecyclerView.setPullRefreshEnabled(true);
xRecyclerView.setLoadingMoreEnabled(true);xRecyclerView.setRefreshProgressStyle(ProgressStyle.BallSpinFadeLoader);xRecyclerView.setLoadingMoreProgressStyle(ProgressStyle.Pacman);xRecyclerView.setLoadingListener(new    XRecyclerView.LoadingListener() {@Overridepublic void onRefresh() {new Handler().postDelayed(new Runnable(){public void run() {getWorksData(1,2);}}, 2000);}@Overridepublic void onLoadMore() {count+=1;loge("第几次加载=="+count);new Handler().postDelayed(new Runnable(){public void run() {getWorksData(count,3);}}, 2000);}});

从上面代码可以看到,需要先设置下拉刷新和加载更多可执行,为true,然后设置它的加载样式,有多种样式可以选择,具体参考xrecyclerview的github介绍,接下里设置一下loadingListener即可.我们需要实现它的两个方法:刷新回调方法onRefresh()和加载更多方法onLoadingMore(),即分别在这两个方法中实现自己的刷新和加载数据逻辑即可.
getWorksData(参数1,参数2)即为获取后天数据的方法.参数1是指数据请求的次数,也指代请求后台的数据页数,初始化为1;参数2表示当前数据的操作模式(为1:初次请求数据,为2:刷新数据,为3:加载更多数据).由于是公司项目,这里我附上okhttp请求的onResponse()方法得到数据后的处理:

loadingDialog.dismiss();
creativeImageBean = JSONObject.parseObject(response, CreativeImageBean.class);
if (creativeImageBean!=null && creativeImageBean.getCode() == 1000) {if(type==1){//是初次加载loge("初次加载数据");data=creativeImageBean.getData().getList();Message msg = Message.obtain(handler);msg.what = GET_DATA;handler.handleMessage(msg);}else if(type==2){//下拉刷新//data = new              ArrayList<CreativeImageBean.CreativeImageList.CreativeImageData>();updateData=creativeImageBean.getData().getList();count = 1;loge("刷新了");xRecyclerView.refreshComplete();if (workAdapter != null) {Message msg = Message.obtain(handler);msg.what = UPDATE_DATA;handler.sendMessage(msg);} else {Message msg = Message.obtain(handler);msg.what = GET_DATA;handler.sendMessage(msg);}}else if(type==3){//加载更多//moreData = new ArrayList<CreativeImageBean.CreativeImageList.CreativeImageData>();moreData = creativeImageBean.getData().getList();loge("加载更多数据页数==" + count+"---数据量--"+moreData.size());if (moreData != null && moreData.size() > 0) {data.addAll(moreData);loge("data加载更多数据后的地址=="+data.hashCode());loge("作品总数据长度==" + data.size());//                                    Message msg = Message.obtain(handler);
//                                    msg.what = UPDATE_DATA;
//                                    handler.sendMessage(msg);if(workAdapter!=null){loge("workAdapter不为空");workAdapter.notifyDataSetChanged();}else {loge("workAdapter为空");workAdapter = new WorksShowAdapter(MemoryWorksActivity.this,data);xRecyclerView.setAdapter(workAdapter);}xRecyclerView.loadMoreComplete();//workAdapter.addNewData(data);//添加数据//如果添加moreData,为空是什么原因} else {loge("moreData数据为空");
//                                    xRecyclerView.setLoadingMoreEnabled(false);
//                                    toast(getString(R.string.act_home_loadmore));xRecyclerView.loadMoreComplete();}}} 

第一次使用markdown写博客,怎么感觉代码很乱…
如果感觉if-else比较乱,可以使用switch-case,数据刷新即需要重新获取后台最新数据,比如用户上传了自己的作品,那么就需要在他将作品上传成功后刷新数据,让用看到自己的作品,而加载更多则是根据用户上拉的操作,判断需要请求的数据页数,并将数据放入原有的data中,然后刷新数据,数据请求和刷新是耗时的,所以开启子线程,部分代码如下:

@Overridepublic void handleMessage(Message msg, Activity weakReferenceActivity) {switch (msg.what) {case GET_DATA://显示数据和处理loge("来获取数据和显示了");xRecyclerView.setLayoutManager(new GridLayoutManager(MemoryWorksActivity.this,2));workAdapter = new WorksShowAdapter(MemoryWorksActivity.this,data);loge("data初始的地址==="+data.hashCode());xRecyclerView.setAdapter(workAdapter);workAdapter.setOnMyItemClickListener(new CreativeImageAdapter.OnMyItemClickListener() {@Overridepublic void onItemClick(View view, int position) {//相关操作}@Overridepublic void onItemLongClick(View view, int position) {}});break;case UPDATE_DATA://刷新数据loge("来刷新数据了,这时data数量为"+data.size());//workAdapter.addNewData(data);data.clear();data.addAll(updateData);workAdapter.notifyDataSetChanged();break;}}
    刷新数据需要先清除原有数据,然后放入最新数据,接着调用adaper.motifyDataSetChange()方法.
问题总览
  1. 点击第i个item,提示却是第i+1个item被点击
    问题原因:xrecyclerrview默认添加的header和footer,这就导致item的真实位置发生了变化,
    解决方案:将item的位置由holder.getLayoutPosition()改为position就可以了,adapter中修改代码如下:
holder.itemView.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {//int pos = holder.getLayoutPosition();//点击的item控件的位置myListener.onItemClick(holder.itemView, position);/*此方法返回的pos值与onBindViewHolder方法传入的position值有可能不同。根据SDK中的解释,在Recyclerview 进行添加、移除item等操作时,position位置可能会变化,而所有的adapter的刷新并不总是及时的,只有这个方法返回的才是当前item经过一些变换后所处的真正位置。*/}});
  1. notifySetDataCahnged()无法刷新数据的问题:
    问题原因:先下拉刷新,然后上拉加载数据为空不显示,因为data的地址发生了变化,数据的刷新是在adapter中实现的,并且是新建一个list,然后调用了list.addAll(data),导致刷新data数据地址改变,刷新无效
    解决方案:新建一个list对象moreData来专门接收下拉刷新的数据,并且摒弃adapter中的addNewData()方法,直接data.clear()—data.addAll(moreData)—adapter.notifyDataChanged()

补充:本文仅做记录和供大家参考,如有需改进和错误之处,欢迎大家留言提出,谢谢!

这篇关于XRecyclerview用法以及遇到的一些问题的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/268493

相关文章

Spring的RedisTemplate的json反序列泛型丢失问题解决

《Spring的RedisTemplate的json反序列泛型丢失问题解决》本文主要介绍了SpringRedisTemplate中使用JSON序列化时泛型信息丢失的问题及其提出三种解决方案,可以根据性... 目录背景解决方案方案一方案二方案三总结背景在使用RedisTemplate操作redis时我们针对

Kotlin Map映射转换问题小结

《KotlinMap映射转换问题小结》文章介绍了Kotlin集合转换的多种方法,包括map(一对一转换)、mapIndexed(带索引)、mapNotNull(过滤null)、mapKeys/map... 目录Kotlin 集合转换:map、mapIndexed、mapNotNull、mapKeys、map

nginx中端口无权限的问题解决

《nginx中端口无权限的问题解决》当Nginx日志报错bind()to80failed(13:Permissiondenied)时,这通常是由于权限不足导致Nginx无法绑定到80端口,下面就来... 目录一、问题原因分析二、解决方案1. 以 root 权限运行 Nginx(不推荐)2. 为 Nginx

解决1093 - You can‘t specify target table报错问题及原因分析

《解决1093-Youcan‘tspecifytargettable报错问题及原因分析》MySQL1093错误因UPDATE/DELETE语句的FROM子句直接引用目标表或嵌套子查询导致,... 目录报js错原因分析具体原因解决办法方法一:使用临时表方法二:使用JOIN方法三:使用EXISTS示例总结报错原

Windows环境下解决Matplotlib中文字体显示问题的详细教程

《Windows环境下解决Matplotlib中文字体显示问题的详细教程》本文详细介绍了在Windows下解决Matplotlib中文显示问题的方法,包括安装字体、更新缓存、配置文件设置及编码調整,并... 目录引言问题分析解决方案详解1. 检查系统已安装字体2. 手动添加中文字体(以SimHei为例)步骤

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

nginx 负载均衡配置及如何解决重复登录问题

《nginx负载均衡配置及如何解决重复登录问题》文章详解Nginx源码安装与Docker部署,介绍四层/七层代理区别及负载均衡策略,通过ip_hash解决重复登录问题,对nginx负载均衡配置及如何... 目录一:源码安装:1.配置编译参数2.编译3.编译安装 二,四层代理和七层代理区别1.二者混合使用举例

全面掌握 SQL 中的 DATEDIFF函数及用法最佳实践

《全面掌握SQL中的DATEDIFF函数及用法最佳实践》本文解析DATEDIFF在不同数据库中的差异,强调其边界计算原理,探讨应用场景及陷阱,推荐根据需求选择TIMESTAMPDIFF或inte... 目录1. 核心概念:DATEDIFF 究竟在计算什么?2. 主流数据库中的 DATEDIFF 实现2.1

MySQL中的LENGTH()函数用法详解与实例分析

《MySQL中的LENGTH()函数用法详解与实例分析》MySQLLENGTH()函数用于计算字符串的字节长度,区别于CHAR_LENGTH()的字符长度,适用于多字节字符集(如UTF-8)的数据验证... 目录1. LENGTH()函数的基本语法2. LENGTH()函数的返回值2.1 示例1:计算字符串

Java中的数组与集合基本用法详解

《Java中的数组与集合基本用法详解》本文介绍了Java数组和集合框架的基础知识,数组部分涵盖了一维、二维及多维数组的声明、初始化、访问与遍历方法,以及Arrays类的常用操作,对Java数组与集合相... 目录一、Java数组基础1.1 数组结构概述1.2 一维数组1.2.1 声明与初始化1.2.2 访问