Android 应用开发-解决RecyclerView循环视图不能正确更新的问题

一、背景介绍

最近2个多月,我一直在开发安卓应用。由于我只是个新手,对Java和Android Studio都了解不深,基本是边学习,边开发。我手头最主要的参考资料就是欧阳燊先生编著的《Android App开发入门与项目实战》,前段时间才看到第12章,了解到了RecyclerView循环视图的妙用,立即就照本宣科的用到了自己开发的一款商品扫描盘点的app中,11月份,该app已经交给公司营销部门的同事进行实测,同事反馈挺好的,帮他们解决了工作中的麻烦。软件的开发并不那么顺利,我遇到了不少的问题,还好都解决了(相关内容见下面的链接)。

SQLite 查询语句遇到的坑——条件语句等号后的参数没用单引号括起来的异常
https://blog.csdn.net/bahamutj/article/details/134044809

Android 应用开发学习-自定义月份选择器
https://blog.csdn.net/bahamutj/article/details/134211869

Android 应用开发-解决使用华为统一扫描服务的app在鸿蒙系统的手机上不能扫码的问题
https://blog.csdn.net/bahamutj/article/details/134341225

由于当时我是照着书上的源代码进行的开发,因为应用场景的不同,导致了编写出的代码存在一些不尽如人意的地方,我个人感觉可以优化,但那款app开发已经完成,我暂时也就不想去修改了。之后又接到另外一个部门同事的需求开发一款危险废物管理方面的app,以帮助同事快速生成二维码和相应的数据记录。这款app也会用到RecyclerView循环视图,我本以为有了之前的经验,这次的开发会很顺利,结果还是遇到了坑。

二、问题描述

前面提到了第一次用到RecyclerView循环视图我是照着《Android App开发入门与项目实战》中的内容填写的代码,存在一些可优化的地方。这次开发,与RecyclerView循环视图相关的代码,有一部分我是重新编写的,没有直接复制之前的代码。结果出了问题。

代码完成后,我照例进行调试,创建了几条测试用的数据记录后,测试在RecyclerView循环视图中的显示情况。RecyclerView循环视图初始化时很正常,从数据库中读取到了数据,并显示在了RecyclerView循环视图中(如下左图,查询到的数据都是2023年的)。我将年度从2023年改成2022年后,软件会再次进行查询。我在创建测试用的数据的时候,特意创建了一条2022年的数据,正常情况下,选择了2022年后,会将数据更新到RecyclerView循环视图中,但这次没有(如下右图)。

    

我又来回了进行调试,结果都一样,进入这个页面时,可以正常显示数据,但更改参数就是不会显示数据,如不切换到其他年度,再换会2023年,也不显示数据。这就很奇怪了。

我之后又在程序中添加了一些Log语句输出相关的信息,通过Android Studio的Logcat检查程序运行过程中Log的输出结果。其中查询数据库后,通过Log语句打印查询结果的个数,发现查询是成功的。并且运行过程中软件没有闪退,也没有警告提示,这可把我整懵了。

三、解决办法

无奈之下,只好求助于万能的度娘,通过一番搜索,结果在CSDN里找到了一篇相关的博文(链接如下):

【错误记录】Android中,notifyDataSetChanged()不能正确更新listView问题

虽然这篇文章是关于ListView的问题,但RecyclerView循环视图是ListView的增强版,用法上也有很多相似之处。仔细看过这篇博文之后,我就大致明白了我所遇到的问题是怎么事了。

这篇博文中的 解决方法② 是这样描述的:
对于Arraylist类型的数据data,只在原对象上修改,不能重新赋值,因为重新赋值实质上改变了data所指向的对象,导致adapter的绑定出现问题,这可能也是notifyDataSetChanged()一个使用条件。

我遇到的问题就是这样的,我软件中的Arraylist类型的变量是mRecordsList,在对年度发生改变后,监听器就会执行如下的语句代码。先是清空mRecordsList,然后进行数据查询,并将结果通过赋值语句传递给mRecordsList,最后通知RecyclerView循环视图的适配器mAdapter,数据发生了变化,由适配器更新RecyclerView循环视图。

问题就出在“mRecordsList = mHelper.query(condition); ” 语句上。

而这些代码正是这次重新编写的代码,之前的app中对mRecordsList的数据更新是用的Add方法,逐条添加的,因此没有出现这个问题。

// 在从数据库查询数据之前,先将当前mRecordsList清空
// mRecordsList是Arraylist类型,该变量存放的数据会显示在RecyclerView循环视图中
if (mRecordsList.size() > 0) {
            mRecordsList.clear();
            mAdapter.notifyDataSetChanged();  // 通知适配器整列数据发生了变化
        }

// 通过数据库帮助器查询符合条件 condition 的数据,并返回给mRecordsList
// 问题就出现在这条赋值语句!!!!!!!
mRecordsList = mHelper.query(condition); 

// 通知适配器语句,下面两条任选一条
//mAdapter.notifyDataSetChanged();  // 通知适配器整列数据发生了变化
mAdapter.notifyItemInserted(0);  // 通知适配器在指定位置插入了新项

找到了症结所在,稍加修改就可以了,修改后的代码如下:

if (mRecordsList.size() > 0) {
            mRecordsList.clear();
            mAdapter.notifyDataSetChanged();  // 通知适配器整列数据发生了变化
        }


List<WasteInfo> tempList = mHelper.query(condition);

mRecordsList.addAll(tempList);

//mAdapter.notifyDataSetChanged();  // 通知适配器整列数据发生了变化
mAdapter.notifyItemInserted(0);  // 通知适配器在指定位置插入了新项

由于逐条添加比较麻烦,我在网上搜索了一下,发现可以用addAll方法将一个Arraylist类型中的元素添加到另外一个Arraylist类型的变量中,这样语句就简洁很多了。

重新运行软件,问题解决。

这次不但解决了一个开发中遇到的问题,还学到了一些新的知识,让我对Java的理解有更深入了一点点。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

武陵悭臾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值