动态添加View至LinearLayout后Tag为空引发空指针异常排查
问题拆解与解决办法
首先,崩溃的直接原因很明确:你在点击事件里强转view.getTag()为Integer时,这个Tag是null,所以触发了NullPointerException。为什么会这样?核心问题出在「设置Tag的时机」和「实际被点击的View对象」不匹配上:
1. 为什么Tag会是null?
你是在所有动态View都添加到leafletList之后,才循环给leafletList的子View设置Tag。但从崩溃堆栈能看到,点击事件是绑定在DrReportLeafletLayout内部的某个View上(DrReportLeafletLayout$1.onClick)——也就是说:
- 你给
leafletList的直接子View(也就是DrReportLeafletLayout实例)设置了Tag,但实际被用户点击的是这个布局内部的控件(比如TextView、按钮),而这些内部控件根本没被设置过Tag; - 退一步说,就算你设置Tag的时机没问题,如果用户在你还没执行循环设置Tag的代码前就点击了View,同样会拿到null。
2. 解决方案:从根源上绑定索引与View
方案一:创建动态View时直接设置Tag
不要等到所有View都添加完再统一设置,而是在创建DrReportLeafletLayout的同时就把索引传进去并设置Tag:
String[] disease = {"Colds","Cough"}; for(int i = 0; i < disease.length ; i++){ DrReportLeafletLayout leaflet = new DrReportLeafletLayout(getActivity(), disease[i], this, disease); // 在这里直接给当前创建的布局设置Tag leaflet.setTag(i); leafletList.addView(leaflet); }
然后修改DrReportLeafletLayout内部的点击事件,确保能拿到外层布局的Tag:
view.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { // 如果点击的是内部子View,就获取它的父布局(DrReportLeafletLayout)的Tag Integer position = (Integer) ((View) view.getParent()).getTag(); fragment.replaceLeaflet(position, data); } });
方案二:让DrReportLeafletLayout直接持有索引
更优雅的方式是,在DrReportLeafletLayout的构造方法里加入一个position参数,把索引存为布局的成员变量,这样点击时直接用这个变量就行,完全不用依赖Tag:
// 修改DrReportLeafletLayout的构造方法 public DrReportLeafletLayout(Context context, String disease, OnClickListener listener, String[] diseaseArray, int position) { super(context); this.mPosition = position; // 其他初始化代码... } // 点击事件里直接用成员变量 view.setOnClickListener(new OnClickListener() { @Override public void onClick(View view) { fragment.replaceLeaflet(mPosition, data); } }); // 添加View的时候传入索引 String[] disease = {"Colds","Cough"}; for(int i = 0; i < disease.length ; i++){ DrReportLeafletLayout leaflet = new DrReportLeafletLayout(getActivity(), disease[i], this, disease, i); leafletList.addView(leaflet); }
3. 额外排查点
- 检查是否有其他地方调用了
setTag(),不小心覆盖了你设置的Tag值; - 确认
leafletList.getChildAt(i)确实是你创建的DrReportLeafletLayout实例,没有混入其他系统或自定义View。
内容的提问来源于stack exchange,提问作者blackHawk
相关产品推荐
相关产品推荐

