You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Android中getIdentifier()获取TextView返回null引发空指针问题求助

解决CardView点击获取文本时的空指针异常问题

我来帮你捋捋这个空指针的问题——报错说foodName是null,说明你通过findViewById(resID)没找到对应的TextView,咱们一步步找原因,再改代码:

问题根源分析

  1. 闭包变量的陷阱:你在循环里用了count = i,但i是循环变量,在Java的匿名内部类(就是你写的OnClickListener)里引用的变量得是final或者“有效final”的。不然当点击事件触发时,count的值可能已经不是你点击的那个CardView对应的索引了,导致生成的idFood(比如foodX)是错的,自然找不到对应的View。
  2. View查找范围错误:你用的是Activity的findViewById(),但如果你的foodX是CardView内部的TextView,那应该从当前点击的CardView里去找子View,而不是整个Activity布局里找,不然肯定找不到。
  3. 缺少空值检查:就算前面都对,也得先确认resID有效、foodName不为null,再调用getText(),不然还是可能炸。

修复后的代码示例

我把关键部分改了,你可以直接参考:

public void setToggleEvent(final GridLayout mainGrid) {
    for (int i = 0; i < mainGrid.getChildCount(); i++){
        // 用final变量保存当前索引,避免闭包问题
        final int currentIndex = i;
        final CardView cardView = (CardView) mainGrid.getChildAt(i);
        
        cardView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // 用Color常量代替硬编码数值,可读性更强
                if(cardView.getCardBackgroundColor().getDefaultColor() == Color.WHITE) {
                    // 生成目标TextView的ID字符串
                    String idFood = "food" + currentIndex;
                    // 获取资源ID
                    int resID = getResources().getIdentifier(idFood, "id", getPackageName());
                    
                    // 从当前点击的CardView内部查找子View,而非全局查找
                    TextView foodName = cardView.findViewById(resID);
                    
                    // 强制空值检查,避免崩溃
                    if(foodName != null) {
                        // 直接获取文本并转为String,避免后续空指针
                        foodData = foodName.getText().toString();
                        selectedVegetables.add(foodData);
                    } else {
                        // 可选:添加提示,方便调试
                        Toast.makeText(VegetablesActivity.this, "未找到对应文本控件", Toast.LENGTH_SHORT).show();
                    }
                    
                    // 修改卡片背景色
                    cardView.setCardBackgroundColor(Color.parseColor("#FF6F00"));
                } else {
                    // CardView需用setCardBackgroundColor修改背景,避免覆盖圆角样式
                    cardView.setCardBackgroundColor(Color.parseColor("#FFFFFF"));
                    Toast.makeText(VegetablesActivity.this, "Food Selected", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }
}

额外优化建议

  • 尽量避免用getIdentifier,如果每个CardView里的TextView是固定位置的子View,直接用cardView.getChildAt(0)(假设是第一个子View)强转为TextView,既高效又不需要依赖ID命名规则。
  • 用Color类的常量(比如Color.WHITE)代替硬编码的颜色数值,减少出错概率。

内容的提问来源于stack exchange,提问作者Marco

火山引擎 最新活动