Android解析JSON生成视图时onClickListener传值始终为最后一个ID的问题
问题分析与解决方案
你遇到的这个问题是Android开发中很常见的闭包变量捕获陷阱,再加上代码里有个完全没必要的内层循环,一起导致了点击所有条目都传递最后一个ID的问题。咱们一步步拆解:
核心问题原因
- 无用的内层循环:你写的
for (int j=0;j<len;j++)完全多余——explrObject是单个书籍的JSON对象,直接取"id"字段就行,这个循环只是重复给books_var.id赋值,对逻辑没有任何帮助。 - 匿名内部类的变量引用陷阱:在循环中给
llVer设置OnClickListener时,匿名内部类会捕获外部的books_var对象引用。由于循环是同步执行的,当你点击视图时,循环早已结束,books_var.id已经被更新为最后一本书的ID,所以不管点哪个条目,都会传递最后一个值。
修正后的代码方案
方案一:使用局部变量保存当前条目ID
在每次循环迭代中创建一个局部变量存储当前书籍的ID,匿名内部类会捕获这个局部变量的当前值副本,而不是引用:
for (int i = 0; i < jsonArray.length(); i++) { JSONObject explrObject = jsonArray.getJSONObject(i); // 直接获取当前书籍ID,移除无用的内层循环 final String currentBookId = explrObject.getString("id"); // 这里保留你原本设置视图内容的代码(比如书名、作者、封面等) llVer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (InternetConnection.checkConnection(getBaseContext())) { Intent ReaderIntent = new Intent(BOOKSActivity.this, READERActivity.class); // 使用局部变量currentBookId,而非全局的books_var.id ReaderIntent.putExtra("book", currentBookId); BOOKSActivity.this.startActivity(ReaderIntent); } } }); }
方案二:用View的Tag存储ID(更推荐的灵活写法)
把当前书籍ID存入视图的tag中,点击时直接从视图本身获取数据,避免变量捕获问题:
for (int i = 0; i < jsonArray.length(); i++) { JSONObject explrObject = jsonArray.getJSONObject(i); String bookId = explrObject.getString("id"); // 这里保留你原本设置视图内容的代码 // 将ID存入当前视图的Tag llVer.setTag(bookId); llVer.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (InternetConnection.checkConnection(getBaseContext())) { // 从点击的视图中取出存储的ID String currentId = (String) v.getTag(); Intent ReaderIntent = new Intent(BOOKSActivity.this, READERActivity.class); ReaderIntent.putExtra("book", currentId); BOOKSActivity.this.startActivity(ReaderIntent); } } }); }
额外提醒
如果你的llVer是循环中重复复用的同一个视图(而非每次循环创建新的视图实例),还要注意:每次循环设置点击事件前,最好先移除之前的点击监听,避免多个点击事件叠加。不过从你描述“当前Activity内的其他显示均正常”来看,应该是每次循环都创建了新的视图条目,所以这个问题可能不存在。
内容的提问来源于stack exchange,提问作者IGentlich
相关产品推荐
相关产品推荐

