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

相关文章

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

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

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Python中你不知道的gzip高级用法分享

《Python中你不知道的gzip高级用法分享》在当今大数据时代,数据存储和传输成本已成为每个开发者必须考虑的问题,Python内置的gzip模块提供了一种简单高效的解决方案,下面小编就来和大家详细讲... 目录前言:为什么数据压缩如此重要1. gzip 模块基础介绍2. 基本压缩与解压缩操作2.1 压缩文

怎样通过分析GC日志来定位Java进程的内存问题

《怎样通过分析GC日志来定位Java进程的内存问题》:本文主要介绍怎样通过分析GC日志来定位Java进程的内存问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、GC 日志基础配置1. 启用详细 GC 日志2. 不同收集器的日志格式二、关键指标与分析维度1.

解读GC日志中的各项指标用法

《解读GC日志中的各项指标用法》:本文主要介绍GC日志中的各项指标用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、基础 GC 日志格式(以 G1 为例)1. Minor GC 日志2. Full GC 日志二、关键指标解析1. GC 类型与触发原因2. 堆

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

MySQL数据库中ENUM的用法是什么详解

《MySQL数据库中ENUM的用法是什么详解》ENUM是一个字符串对象,用于指定一组预定义的值,并可在创建表时使用,下面:本文主要介绍MySQL数据库中ENUM的用法是什么的相关资料,文中通过代码... 目录mysql 中 ENUM 的用法一、ENUM 的定义与语法二、ENUM 的特点三、ENUM 的用法1

JavaSE正则表达式用法总结大全

《JavaSE正则表达式用法总结大全》正则表达式就是由一些特定的字符组成,代表的是一个规则,:本文主要介绍JavaSE正则表达式用法的相关资料,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录常用的正则表达式匹配符正则表China编程达式常用的类Pattern类Matcher类PatternSynta

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二