Android循环创建按钮时所有ID均指向首个按钮如何解决?
问题根因
你的问题核心是所有动态创建的按钮ID重复:Resources.getIdentifier()只能返回你提前在res/values/ids.xml中预声明的ID资源值,你没有提前声明gi_button1、gi_button2...一系列ID的情况下,这个方法的返回值永远是0。你给所有按钮设置的ID都是0,调用findViewById(0)时,系统会返回布局中第一个ID为0的View,也就是你创建的第一个按钮。
你可以在原循环里加一行Log打印id的值,就能验证所有按钮的ID都是0。
修复方案
下面提供3种可行的修复方案,按需选择即可:
方案1:预声明所有ID(适合按钮总数固定的场景)
- 在
res/values目录下新建ids.xml文件,把你需要用到的所有按钮ID提前声明:
<?xml version="1.0" encoding="utf-8"?> <resources> <item name="gi_button1" type="id" /> <item name="gi_button2" type="id" /> <!-- 一直写到你需要的最大序号,比如gi_button100 --> </resources>- 保持你原有创建、获取按钮的逻辑不变,此时
getIdentifier()就能返回唯一的正确ID,不会再出现重复问题。
- 在
方案2:动态生成唯一ID+映射存储(适合按钮总数不固定的场景)
Android API 17及以上提供了View.generateViewId()方法,可以生成系统保证全局唯一的ID,不用预定义资源:- 在类中新增成员变量存储按钮序号和实例的映射:
// 类成员变量 private SparseArray<Button> buttonMap = new SparseArray<>();- 替换原循环中设置ID的代码:
// 删除原有getIdentifier相关的两行代码 int id = View.generateViewId(); btn.setId(id); // 存储序号和按钮实例的映射 buttonMap.put(i, btn);- 后续需要取对应序号的按钮时,直接从映射中取即可:
Button button = buttonMap.get(100); Log.d("Hello", button.getText().toString());如果需要兼容API 17以下的版本,可以自己实现一个简单的ID生成工具类即可。
方案3:直接从父布局取子View(最简便的方案)
你所有按钮都是按顺序添加到同一个LinearLayout中的,需要取第N个按钮时,直接通过父布局的子View索引获取即可,完全不用处理ID逻辑:// 取第100个按钮,因为子View索引从0开始,所以要减1 Button button = (Button) linearLayout.getChildAt(100-1); Log.d("Hello", button.getText().toString());
另外你原测试代码里的button.getText.toString()存在语法错误,应该是button.getText().toString(),注意不要漏了方法括号。
内容的提问来源于stack exchange,提问作者furst
相关产品推荐
相关产品推荐

