Android开发:Button.setEnabled()触发NullPointerException求助
首先咱们来定位你遇到的核心问题:绝对不能假设Android布局中控件的ID是连续的整数。你代码里用findViewById(R.id.vtl_stage11_00 + k)这种方式获取控件,完全不可靠——Android在编译时会给每个资源ID分配唯一的int值,这些值并不会按照你命名的顺序连续递增。
你看到ccl_stage11没报错,只是巧合它对应的几个ID刚好在数值上连续,但这是非常危险的写法,后续布局修改或者SDK版本更新都可能让它也出问题。而vtl和hrl的ID显然不符合这个“连续”的假设,所以findViewById返回了null,调用setEnabled(false)时就触发了NullPointerException。
具体解决方案
方案1:逐个明确初始化(最可靠)
直接用每个按钮的真实ID来初始化数组元素,彻底摆脱对ID数值连续性的依赖:
protected void buttonSettings() { // 初始化ccl_stage11(修正原有的危险写法) ccl_stage11[1][1] = findViewById(R.id.ccl_stage11_11); ccl_stage11[1][2] = findViewById(R.id.ccl_stage11_12); ccl_stage11[1][3] = findViewById(R.id.ccl_stage11_13); ccl_stage11[2][1] = findViewById(R.id.ccl_stage11_21); ccl_stage11[2][2] = findViewById(R.id.ccl_stage11_22); ccl_stage11[2][3] = findViewById(R.id.ccl_stage11_23); ccl_stage11[3][1] = findViewById(R.id.ccl_stage11_31); ccl_stage11[3][2] = findViewById(R.id.ccl_stage11_32); ccl_stage11[3][3] = findViewById(R.id.ccl_stage11_33); // 设置ccl的enabled状态 for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { ccl_stage11[i][j].setEnabled(false); } } // 初始化vtl_stage11 vtl_stage11[0][0] = findViewById(R.id.vtl_stage11_00); vtl_stage11[0][1] = findViewById(R.id.vtl_stage11_01); vtl_stage11[0][2] = findViewById(R.id.vtl_stage11_02); vtl_stage11[0][3] = findViewById(R.id.vtl_stage11_03); vtl_stage11[1][0] = findViewById(R.id.vtl_stage11_10); vtl_stage11[1][1] = findViewById(R.id.vtl_stage11_11); vtl_stage11[1][2] = findViewById(R.id.vtl_stage11_12); vtl_stage11[1][3] = findViewById(R.id.vtl_stage11_13); vtl_stage11[2][0] = findViewById(R.id.vtl_stage11_20); vtl_stage11[2][1] = findViewById(R.id.vtl_stage11_21); vtl_stage11[2][2] = findViewById(R.id.vtl_stage11_22); vtl_stage11[2][3] = findViewById(R.id.vtl_stage11_23); vtl_stage11[3][0] = findViewById(R.id.vtl_stage11_30); vtl_stage11[3][1] = findViewById(R.id.vtl_stage11_31); vtl_stage11[3][2] = findViewById(R.id.vtl_stage11_32); vtl_stage11[3][3] = findViewById(R.id.vtl_stage11_33); // 初始化hrl_stage11 hrl_stage11[0][0] = findViewById(R.id.hrl_stage11_00); hrl_stage11[0][1] = findViewById(R.id.hrl_stage11_01); hrl_stage11[0][2] = findViewById(R.id.hrl_stage11_02); hrl_stage11[0][3] = findViewById(R.id.hrl_stage11_03); hrl_stage11[1][0] = findViewById(R.id.hrl_stage11_10); hrl_stage11[1][1] = findViewById(R.id.hrl_stage11_11); hrl_stage11[1][2] = findViewById(R.id.hrl_stage11_12); hrl_stage11[1][3] = findViewById(R.id.hrl_stage11_13); hrl_stage11[2][0] = findViewById(R.id.hrl_stage11_20); hrl_stage11[2][1] = findViewById(R.id.hrl_stage11_21); hrl_stage11[2][2] = findViewById(R.id.hrl_stage11_22); hrl_stage11[2][3] = findViewById(R.id.hrl_stage11_23); hrl_stage11[3][0] = findViewById(R.id.hrl_stage11_30); hrl_stage11[3][1] = findViewById(R.id.hrl_stage11_31); hrl_stage11[3][2] = findViewById(R.id.hrl_stage11_32); hrl_stage11[3][3] = findViewById(R.id.hrl_stage11_33); // 设置vtl和hrl的enabled状态 for(int i=0;i<=3;i++){ for (int j =0;j<=3;j++){ vtl_stage11[i][j].setEnabled(false); hrl_stage11[i][j].setEnabled(false); } } // 启用指定按钮 ccl_stage11[1][3].setEnabled(true); ccl_stage11[3][1].setEnabled(true); }
方案2:动态获取资源ID(更简洁)
如果你的按钮ID命名严格遵循vtl_stage11_ij和hrl_stage11_ij的格式(比如vtl_stage11_00、vtl_stage11_01...vtl_stage11_33),可以用getResources().getIdentifier()动态获取ID,避免重复代码:
protected void buttonSettings() { // 初始化ccl_stage11(用动态方式) for (int i = 1; i <= 3; i++) { for (int j = 1; j <= 3; j++) { String idName = "ccl_stage11_" + i + j; int resId = getResources().getIdentifier(idName, "id", getPackageName()); ccl_stage11[i][j] = findViewById(resId); ccl_stage11[i][j].setEnabled(false); } } // 初始化vtl_stage11和hrl_stage11 for (int i = 0; i <= 3; i++) { for (int j = 0; j <= 3; j++) { // 格式化i和j为两位数字,匹配ID命名格式 String vtlIdName = "vtl_stage11_" + String.format("%02d", i) + String.format("%02d", j); String hrlIdName = "hrl_stage11_" + String.format("%02d", i) + String.format("%02d", j); int vtlResId = getResources().getIdentifier(vtlIdName, "id", getPackageName()); int hrlResId = getResources().getIdentifier(hrlIdName, "id", getPackageName()); vtl_stage11[i][j] = findViewById(vtlResId); hrl_stage11[i][j] = findViewById(hrlResId); } } // 设置enabled状态 for(int i=0;i<=3;i++){ for (int j =0;j<=3;j++){ vtl_stage11[i][j].setEnabled(false); hrl_stage11[i][j].setEnabled(false); } } ccl_stage11[1][3].setEnabled(true); ccl_stage11[3][1].setEnabled(true); }
额外检查点
- 确认
activity_stage11.xml中所有的vtl_stage11_xx和hrl_stage11_xx按钮都存在,ID拼写完全正确(大小写、数字都不能出错)。 - 如果使用动态ID方式,确保ID命名格式和代码中的拼接逻辑一致,比如如果你的按钮ID是
vtl_stage11_0_0而不是vtl_stage11_00,就要修改代码中的字符串拼接部分。
内容的提问来源于stack exchange,提问作者Albert
相关产品推荐
相关产品推荐

