Android ListView中开启线程查询更新数据导致的ViewHolder错乱问题解决

最近项目中遇到了一个比较有趣的问题。


项目里有一些老代码使用的不是RecyclerView而是ListView。在更新界面过程中,涉及到数据的查询,于是开启了一个线程池去查询。


查询的调用是这样的FileSizeUtil.getInstance().setDirLabel(mContext, f, vh.info);

 vh.info就是在ViewHolder中保存的TextView用来展示查询到的数据。然后界面的现象是,更新的数据第一行总是有误。

于是我在更新界面的地方加入了打印vh.info 以及查询结果的打印


Line 1659: 11-01 20:27:47.912 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/amap
Line 1671: 11-01 20:27:47.917 11295 11295 I zhang5555:  positon 4 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1672: 11-01 20:27:47.917 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/Android
Line 1681: 11-01 20:27:47.923 11295 11295 I zhang5555:  positon 5 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1682: 11-01 20:27:47.923 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/backups
Line 1690: 11-01 20:27:47.928 11295 11295 I zhang5555:  positon 6 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1691: 11-01 20:27:47.928 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/bcr
Line 1699: 11-01 20:27:47.933 11295 11295 I zhang5555:  positon 7 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1700: 11-01 20:27:47.933 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/Browser
Line 1708: 11-01 20:27:47.939 11295 11295 I zhang5555:  positon 0 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1709: 11-01 20:27:47.939 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/1
Line 1717: 11-01 20:27:47.944 11295 11295 I zhang5555:  positon 1 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1718: 11-01 20:27:47.944 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/123
Line 1724: 11-01 20:27:47.946 11295 11295 I zhang5555:  positon 2 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1727: 11-01 20:27:47.947 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/Alarms
Line 1730: 11-01 20:27:47.948 11295 11295 I zhang5555:  positon 3 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1731: 11-01 20:27:47.949 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/amap
Line 1737: 11-01 20:27:47.951 11295 11295 I zhang5555:  positon 4 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1740: 11-01 20:27:47.951 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/Android
Line 1754: 11-01 20:27:47.953 11295 11295 I zhang5555:  positon 5 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1756: 11-01 20:27:47.953 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/backups
Line 1763: 11-01 20:27:47.956 11295 11295 I zhang5555:  positon 6 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}
Line 1764: 11-01 20:27:47.956 11295 11295 I zhang5566666: TextView android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info} path /storage/emulated/0/bcr
Line 1770: 11-01 20:27:47.958 11295 11295 I zhang5555:  positon 7 VIEWHOLDER android.widget.TextView{3b6ae2a V.ED..... ......ID 0,0-0,0 #7f0600e1 app:id/dir_list_info}


简单说下这个打印的内容 position是 在listview展示的位置,VIEWHOLDER android.widget.TextView{3b6ae2a这里是穿进去的TextView控件直接打印,这样可以区分是哪个TextView对象。 这是截取的有问题的一部分,可以发现更新的都是同一个TextView。  



这里自己思考了一下 因为我的查询是开启了线程去查询,结束后在更新到界面的。 应该是由于在这个过程中ViewHolder 被复用了。比如 在开启线程查询时 是 在第一行位置发出的查询,等到查询结束。 这个传入的ViewHolder.TextView 已经不在当时的第一行了(因为在其他行被复用了)。所以导致了界面上展示的数据有误。



好了,说一下解决办法。就是利用View的setTag 和getTag。 放到我这个问题上是这样的,因为我展示的内容是根据一个文件的路径去查询其子文件夹的数量,并把数量展示出来。 那我们就可以在传入时

        vh.info.setTag(path);
        FileSizeUtil.getInstance().setDirLabel(mContext, f, vh.info);


path 是路径。

等到更新内容时加入判断,


                        if (str != null && infoView.getTag().equals(path)){
                            infoView.setText(str);
                        }


在判断时的这个path 是你在开启线程查询时保存的。 利用这个判断 就可以避免数据更新到变更位置后的ViewHolder上。

当然 在我这个问题中使用的是path ,大家要根据自己的问题找到这个每行数据独特的地方去保存在tag中,后面在取出判断。

这个独特的地方就类似于数据库中的主键一样。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值