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

相关文章

mapstruct中的@Mapper注解的基本用法

《mapstruct中的@Mapper注解的基本用法》在MapStruct中,@Mapper注解是核心注解之一,用于标记一个接口或抽象类为MapStruct的映射器(Mapper),本文给大家介绍ma... 目录1. 基本用法2. 常用属性3. 高级用法4. 注意事项5. 总结6. 编译异常处理在MapSt

java中long的一些常见用法

《java中long的一些常见用法》在Java中,long是一种基本数据类型,用于表示长整型数值,接下来通过本文给大家介绍java中long的一些常见用法,感兴趣的朋友一起看看吧... 在Java中,long是一种基本数据类型,用于表示长整型数值。它的取值范围比int更大,从-922337203685477

MyBatis ResultMap 的基本用法示例详解

《MyBatisResultMap的基本用法示例详解》在MyBatis中,resultMap用于定义数据库查询结果到Java对象属性的映射关系,本文给大家介绍MyBatisResultMap的基本... 目录MyBATis 中的 resultMap1. resultMap 的基本语法2. 简单的 resul

Python主动抛出异常的各种用法和场景分析

《Python主动抛出异常的各种用法和场景分析》在Python中,我们不仅可以捕获和处理异常,还可以主动抛出异常,也就是以类的方式自定义错误的类型和提示信息,这在编程中非常有用,下面我将详细解释主动抛... 目录一、为什么要主动抛出异常?二、基本语法:raise关键字基本示例三、raise的多种用法1. 抛

MySQL 设置AUTO_INCREMENT 无效的问题解决

《MySQL设置AUTO_INCREMENT无效的问题解决》本文主要介绍了MySQL设置AUTO_INCREMENT无效的问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参... 目录快速设置mysql的auto_increment参数一、修改 AUTO_INCREMENT 的值。

关于跨域无效的问题及解决(java后端方案)

《关于跨域无效的问题及解决(java后端方案)》:本文主要介绍关于跨域无效的问题及解决(java后端方案),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录通用后端跨域方法1、@CrossOrigin 注解2、springboot2.0 实现WebMvcConfig

Go语言中泄漏缓冲区的问题解决

《Go语言中泄漏缓冲区的问题解决》缓冲区是一种常见的数据结构,常被用于在不同的并发单元之间传递数据,然而,若缓冲区使用不当,就可能引发泄漏缓冲区问题,本文就来介绍一下问题的解决,感兴趣的可以了解一下... 目录引言泄漏缓冲区的基本概念代码示例:泄漏缓冲区的产生项目场景:Web 服务器中的请求缓冲场景描述代码

Java死锁问题解决方案及示例详解

《Java死锁问题解决方案及示例详解》死锁是指两个或多个线程因争夺资源而相互等待,导致所有线程都无法继续执行的一种状态,本文给大家详细介绍了Java死锁问题解决方案详解及实践样例,需要的朋友可以参考下... 目录1、简述死锁的四个必要条件:2、死锁示例代码3、如何检测死锁?3.1 使用 jstack3.2

解决JSONField、JsonProperty不生效的问题

《解决JSONField、JsonProperty不生效的问题》:本文主要介绍解决JSONField、JsonProperty不生效的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑... 目录jsONField、JsonProperty不生效javascript问题排查总结JSONField

github打不开的问题分析及解决

《github打不开的问题分析及解决》:本文主要介绍github打不开的问题分析及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、找到github.com域名解析的ip地址二、找到github.global.ssl.fastly.net网址解析的ip地址三