NavigationDrawer中无子女项的ExpandableListView空指针异常求助
解决ExpandableListView无子女项头部菜单导致的NullPointerException问题
嘿,我之前也遇到过一模一样的问题!你的崩溃原因很清晰:那些没有子项的头部菜单(比如Home、Jaipur这些),在listDataChild这个HashMap里找不到对应的条目,调用listDataChild.get(...)会返回null,而你在适配器的getChildrenCount和getChild方法里直接对这个null对象调用.size()或.get(),自然就触发NullPointerException了。
修复步骤:
1. 确保所有头部菜单都有对应的子项列表(哪怕是空列表)
在初始化数据的时候,先给所有头部菜单都绑定一个空的ArrayList,再覆盖那些有实际子项的条目。这样listDataChild里就不会存在找不到键的情况:
listDataHeader.add("Home"); listDataHeader.add("Bhopal"); listDataHeader.add("Indore"); listDataHeader.add("Jaipur"); listDataHeader.add("Udaipur"); listDataHeader.add("Ajmer"); listDataHeader.add("Jodhpur"); listDataHeader.add("Chandigarh"); listDataHeader.add("Lakhnow"); // 先给所有头部初始化空列表,避免HashMap.get()返回null for(String header : listDataHeader) { listDataChild.put(header, new ArrayList<>()); } // 再添加有实际子项的内容 List<String> bhopal_ = new ArrayList<String>(); bhopal_.add("About Us"); bhopal_.add("Board Members"); bhopal_.add("Chaiman Messages"); listDataChild.put(listDataHeader.get(1), bhopal_); List<String> indore_ = new ArrayList<String>(); indore_.add("Heritage of Indore"); indore_.add("City Map"); listDataChild.put(listDataHeader.get(2), indore_); List<String> udaipur_ = new ArrayList<String>(); udaipur_.add("Live"); udaipur_.add("Old"); listDataChild.put(listDataHeader.get(4), udaipur_); List<String> lakhnow_ = new ArrayList<String>(); lakhnow_.add("Procurement"); lakhnow_.add("Schemes"); lakhnow_.add("Auctions"); listDataChild.put(listDataHeader.get(8), lakhnow_);
2. 给适配器添加Null安全检查(双重保障)
虽然第一步已经避免了null,但为了让代码更健壮,还是在适配器的关键方法里加个判断,防止意外情况:
修改getChildrenCount方法:
@Override public int getChildrenCount(int groupPosition) { List<String> childList = listDataChild.get(listDataHeader.get(groupPosition)); // 如果子列表为null,返回0,避免空指针 return childList != null ? childList.size() : 0; }
修改getChild方法:
@Override public Object getChild(int groupPosition, int childPosititon) { List<String> childList = listDataChild.get(listDataHeader.get(groupPosition)); // 确保子列表不为null且索引有效,否则返回空字符串 return childList != null && childPosititon < childList.size() ? childList.get(childPosititon) : ""; }
3. 优化用户体验(可选)
如果不想让没有子项的头部显示展开/收起箭头,可以在getGroupView里判断子项数量,隐藏箭头控件(前提是你的头部布局里有箭头ImageView):
@Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { String header_title = (String) getGroup(groupPosition); if (convertView == null) { LayoutInflater infalInflater = (LayoutInflater) this.mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = infalInflater.inflate(R.layout.sub_menu_list_group, null); } TextView tv_head_txt = (TextView) convertView.findViewById(R.id.lblListHeader); tv_head_txt.setText(header_title); tv_head_txt.setTypeface(Utilities.myFont(mContext)); // 隐藏无子女项的展开箭头 ImageView expandIcon = convertView.findViewById(R.id.expand_icon); if(expandIcon != null) { int childCount = getChildrenCount(groupPosition); if(childCount == 0) { expandIcon.setVisibility(View.GONE); } else { expandIcon.setVisibility(View.VISIBLE); // 根据展开状态切换箭头图标 expandIcon.setImageResource(isExpanded ? R.drawable.ic_collapse_arrow : R.drawable.ic_expand_arrow); } } return convertView; }
这样修改后,不管有没有子项的头部菜单,都能正常显示,不会再崩溃啦!
内容的提问来源于stack exchange,提问作者developer
相关产品推荐
相关产品推荐

