我正在开发一个Android应用程序,它实现了一个带有ExpandableListView菜单的导航抽屉,在这个视图中,一些元素应该有子节点,而其他元素在点击时必须执行操作,没有子节点。 我的问题是我有一些随机崩溃,我无法理解可能导致它的原因。这是错误代码:
E / AndroidRuntime:致命异常:主要 过程:com.toptainer.www,PID:9722 java.lang.NullPointerException:尝试调用虚方法' void android.widget.TextView.setText(java.lang.CharSequence)'在null对象引用上 在com.example.nignog.toptainer.ExpandableListAdapter.getChildView(Success.java:377)
点击一个空组,然后点击一个包含子项的组,应用程序通常会崩溃,但它不会让应用程序崩溃。
无论如何,这是我的代码:
首先,我的适配器:
class ExpandableListAdapter extends BaseExpandableListAdapter {
private Context _context;
private List<String> _listDataHeader;
private HashMap<String, List<String>> _listDataChild;
public ExpandableListAdapter(Context context, List<String> listDataHeader,
HashMap<String, List<String>> listChildData) {
this._context = context;
this._listDataHeader = listDataHeader;
this._listDataChild = listChildData;
}
@Override
public Object getChild(int groupPosition, int childPosititon) {
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.get(childPosititon);
}
@Override
public long getChildId(int groupPosition, int childPosition) {
return childPosition;
}
@Override
public View getChildView(int groupPosition, final int childPosition,
boolean isLastChild, View convertView, ViewGroup parent) {
if(getChildrenCount(groupPosition)>1){
final String childText = (String) getChild(groupPosition, childPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.menu_item, null);
}
TextView txtListChild = (TextView) convertView
.findViewById(R.id.textoOpcion);
txtListChild.setText(childText);
}
else{
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.empty_item, null);
}
return convertView;
}
@Override
public int getChildrenCount(int groupPosition) {
if(this._listDataChild.get(this._listDataHeader.get(groupPosition))
!= null){
return this._listDataChild.get(this._listDataHeader.get(groupPosition))
.size();
}
return 1;
}
@Override
public Object getGroup(int groupPosition) {
return this._listDataHeader.get(groupPosition);
}
@Override
public int getGroupCount() {
return this._listDataHeader.size();
}
@Override
public long getGroupId(int groupPosition) {
return groupPosition;
}
@Override
public View getGroupView(int groupPosition, boolean isExpanded,
View convertView, ViewGroup parent) {
String headerTitle = (String) getGroup(groupPosition);
if (convertView == null) {
LayoutInflater infalInflater = (LayoutInflater) this._context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
convertView = infalInflater.inflate(R.layout.menu_item, null);
}
TextView lblListHeader = (TextView) convertView
.findViewById(R.id.textoOpcion);
lblListHeader.setTypeface(null, Typeface.BOLD);
lblListHeader.setText(headerTitle);
ImageView icon = (ImageView) convertView.findViewById(R.id.Icono);
int[] iconos = {R.drawable.ic_user, R.drawable.ic_camion, R.drawable.ic_box, R.drawable.ic_file, R.drawable.ic_report, android.R.drawable.ic_delete};
icon.setImageResource(iconos[groupPosition]);
if(groupPosition == 0) {
convertView.setBackgroundColor(Color.BLACK);
lblListHeader.setTextColor(Color.WHITE);
}
else {
convertView.setBackgroundColor(Color.WHITE);
}
return convertView;
}
@Override
public boolean hasStableIds() {
return false;
}
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
if(getChildrenCount(groupPosition)!=1)return true;
return false;
}
}
活动onCreate方法:
android.support.v7.app.ActionBar ab = getSupportActionBar();
ab.setHomeAsUpIndicator(R.drawable.hamburger_button);
ab.setDisplayHomeAsUpEnabled(true);
expandableList= (ExpandableListView) findViewById(R.id.left_drawer);
mDrawerLayout = (DrawerLayout)findViewById(R.id.drawer_layout);
mActivityTitle = getTitle().toString();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setHomeButtonEnabled(true);
String[] accionesMenu = {getSharedPreferences("Data",Context.MODE_PRIVATE).getString("Usuario", "NOUSER"), "Orden de viaje Emitidas", "Órdenes de viaje en Descarga","Órdenes de viaje en Tránsito","Órdenes de viaje Entregadas","Órdenes de viaje en Carga", "Órdenes de transporte","Guías pendientes", "Reporte", "Desconectar"};
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
expandableList = (ExpandableListView) findViewById(R.id.left_drawer);
prepareListData();
mMenuAdapter = new ExpandableListAdapter(this, listDataHeader, listDataChild);
// setting list adapter
expandableList.setAdapter(mMenuAdapter);
expandableList.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
@Override
public boolean onGroupClick(ExpandableListView parent, View v,
int groupPosition, long id) {
boolean booleano = expandableList.isGroupExpanded(groupPosition);
for(int i =0; i<5; i++){
if(expandableList.isGroupExpanded(i)) expandableList.collapseGroup(i);}
if(!booleano) expandableList.expandGroup(groupPosition);
if (groupPosition == 3) startGuiasActivity();
if (groupPosition == 5) {
startLoginActivity();
}
return true;
}
});
expandableList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v,
int groupPosition, int childPosition, long id) {
if (groupPosition == 1) {
if (childPosition == 0) startOrdenesDeViajeActivity();
if (childPosition == 1) startOrdenesDeViajeDescargaActivity();
if (childPosition == 2) startOrdenesDeViajeTransitoActivity();
if (childPosition == 3) startOrdenesDeViajeEntregadasActivity();
if (childPosition == 4) startOrdenesDeViajeCargaActivity();
}
return false;
}
});
这是我的prepareData方法:
private void prepareListData() {
listDataHeader = new ArrayList<String>();
listDataChild = new HashMap<String, List<String>>();
// Adding data header
listDataHeader.add(getSharedPreferences("Data", Context.MODE_PRIVATE).getString("Usuario", "NOUSER"));
listDataHeader.add("Órdenes de Viaje");
listDataHeader.add("Órdenes de Transporte");
listDataHeader.add("Guías Pendientes");
listDataHeader.add("Reporte");
listDataHeader.add("Desconectar");
// Adding child data
List<String> heading1= new ArrayList<String>();
heading1.add("Emitidas");
heading1.add("En proceso de Descarga");
heading1.add("En tránsito");
heading1.add("Entregadas");
heading1.add("En proceso de Carga");
listDataChild.put(listDataHeader.get(1), heading1);
}
非常感谢任何帮助。
答案 0 :(得分:0)
在getChildView()
TextView txtListChild = (TextView) convertView.findViewById(R.id.textoOpcion);
txtListChild
以某种方式null
。这就是你获得NullPointerException
的原因。
为什么?
原因是你为不同的情况夸大了不同的布局 -
R.layout.menu_item
适用于有孩子和有孩子的团体
R.layout.empty_item
查看没有孩子的群组
但是只有在
时才会给视图充气if (convertView == null)
并且在这种情况下假设最后一个视图膨胀是R.layout.empty_item
,如果下一个项目是没有孩子的组,
if (convertView == null)
将返回false,因此R.layout.menu_item
不会被夸大,它将重用R.layout.empty_item
。在这种情况下,您将不会拥有textView
(将为空)。这将为您提供NullPointerException。
解决方案
您必须通过使其父布局不同来更改2个布局。
假设R.layout.empty_item
的父级布局为RelativeLayout
,R.layout.menu_item
的父布局为LinearLayout
。
更改你的getView() -
if(getChildrenCount(groupPosition)>1){
if(converterView == null || converterView.getClass() == RelativeLayout.class){
converterView = inflater.inflate(R.layout.menu_item, null);
TextView txtListChild = (TextView) convertView
.findViewById(R.id.textoOpcion);
txtListChild.setText(childText);
}
}
else{
if(converterView == null || converterView.getClass() == LinearLayout.class){
converterView = inflater.inflate(R.layout.empty_item, null);
}
}
return converterView;
希望这会有所帮助!