You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android解析JSON生成视图时onClickListener传值始终为最后一个ID的问题

问题分析与解决方案

你遇到的这个问题是Android开发中很常见的闭包变量捕获陷阱,再加上代码里有个完全没必要的内层循环,一起导致了点击所有条目都传递最后一个ID的问题。咱们一步步拆解:

核心问题原因

  1. 无用的内层循环:你写的for (int j=0;j<len;j++)完全多余——explrObject是单个书籍的JSON对象,直接取"id"字段就行,这个循环只是重复给books_var.id赋值,对逻辑没有任何帮助。
  2. 匿名内部类的变量引用陷阱:在循环中给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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:18:14