在我的应用中,我有点像在邮件中附加文件。这些附加文件显示在带有适配器的RecyclerView中。 RV的每个项目都有其自己的btn可以将其删除。问题是当我在列表中有两个项目并尝试删除1个项目而不是第二个项目时,我收到了错误消息。但是,当我尝试删除第二项,然后删除第一项时,一切正常。我使用调试器并设法找到有问题的行,但我不知道如何解决此问题。因此,这是适配器中用于从列表中删除项目的代码:
val array = Singleton.array
if (array!!.size() > 0) {
for (i in 0 until array.size()) {
val obj = array.get(i).asJsonObject
if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) {
array.remove(obj)
mNames.removeAt(position)
Singleton.array = array
updateNames(mNames)
}
}
}
我在此行遇到问题:
val obj = array.get(i).asJsonObject
我通过记录器检查了此变量,一切似乎都正常,我可以用0索引获得值。然后我认为问题出在我向适配器发送数据的地方,但是一切正常。我使用了调试器,并看到方法getAsJsonObject()抛出此异常:
为什么会发生以及如何解决此错误。我试图改变这一点:
for (i in 0 until array.size())
与此for (i in 0 until array.size()-1)
并没有起作用。然后,我尝试将此循环更改为此for (i in 1 until array.size())
,但它也无济于事。那么,我在哪里犯了错误,以及将来如何预防该问题?
P.S。很抱歉附加调试器的屏幕截图,因为我无法从中获取文本数据。
答案 0 :(得分:4)
您已从源数组中删除了元素,这就是为什么会出现异常,因此请使用新数组作为过滤后的值
下面一行的问题
array.remove(obj)
解决方案:
val positionsForRemove = ArrayList<Int>(),
val array = Singleton.array
if (array!!.size() > 0) {
for (i in 0 until array.size()) {
val obj = array.get(i).asJsonObject
if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position])
positionsForRemove.add(position)
}
for(position in positionsForRemove){
array.remove(position)
mNames.remove(position)
}
Singleton.array = array
updateNames(mNames)
}
答案 1 :(得分:3)
您正在for循环迭代中使用remove方法,该方法可以动态更改数组大小。
如果您只需要删除一项,请参阅@Jeeva的答案。
如果要一次从列表中删除多个职位,则必须参考以下方法从数组中删除项目。
val removePositions = ArrayList<Int>(),
val array = Singleton.array
if (array!!.size() > 0) {
for (i in 0 until array.size()) {
val obj = array.get(i).asJsonObject
if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position])
//array.remove(obj)
//mNames.removeAt(position)
removePositions.add(position)
//Singleton.array = array
//updateNames(mNames)
}
for (i in 0 until removePositions.size()) {
array.remove(removePositions[i])
mNames.remove(removePositions[i])
}
Singleton.array = array
updateNames(mNames)
}
答案 2 :(得分:1)
只需在if条件内添加break语句。
val array = Singleton.array
if (array!!.size() > 0) {
for (i in 0 until array.size()) {
val obj = array.get(i).asJsonObject
if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) {
array.remove(obj)
mNames.removeAt(position)
Singleton.array = array
updateNames(mNames)
break;
}
}
}
删除第一个元素后获得异常的原因是删除第一个元素后将执行循环。
但是如果您中断了,则下次不会执行。
没有获得异常的原因当您尝试删除第二个元素时,循环恰好在删除第二个元素之后结束。
答案 3 :(得分:0)
亲爱的朋友们,我似乎可以解决此问题,但不确定,因此需要您的检查。因此,我在条件下添加了return语句:
if (obj.get("filename").toString().substring(1, obj.get("filename").toString().length - 1) == mNames[position]) {
array.remove(obj)
mNames.removeAt(position)
Singleton.array = array
updateNames(mNames)
return@setButton
}
因此,当我满足此条件时,我将从删除过程中返回。我想我知道我的应用有时会崩溃的原因-我在警报对话框中按了yes btn,我的对象已从数组中删除,但我的循环继续工作并检查。但是也许我又错了:)