当某些组为空时,ExpandableListView 崩溃
ExpandableListView crashes when some groups are empty
我正在开发一个 Android 应用程序,它实现了带有 ExpandableListView 菜单的导航抽屉,在此视图中,一些元素应该有子元素,而其他元素在单击时必须执行操作,没有子元素.
我的问题是我有一些随机崩溃,我不明白是什么导致了它。这是错误代码:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.toptainer.www, PID: 9722
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference
at com.example.nignog.toptainer.ExpandableListAdapter.getChildView(Success.java:377)
单击空组然后单击具有 children 的组时,应用程序通常会崩溃,但它不会总是使应用程序崩溃。
无论如何这是我的代码:
首先这是我的适配器:
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;
}
}
Activity的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);
}
如有任何帮助,我们将不胜感激。
在你的getChildView()
TextView txtListChild = (TextView) convertView.findViewById(R.id.textoOpcion);
txtListChild
是 null
不知何故。这就是为什么你得到 NullPointerException
.
Why ?
原因是你在为不同的情况膨胀不同的布局 -
R.layout.menu_item
组 children 和
R.layout.empty_item
没有 child
组的视图
但只有在
时你才会膨胀视图
if (convertView == null)
在这种情况下,假设最后一个膨胀的视图是 R.layout.empty_item
,如果下一个项目是没有 child 的组,则
if (convertView == null)
将 return 为假,因此您的 R.layout.menu_item
不会被夸大,它会重复使用 R.layout.empty_item
。在这种情况下,您将不会拥有 textView
(将为空)。这会给你 NullPointerException。
Solution
您必须通过使它们的 parent 布局不同来更改这 2 个布局。
假设 R.layout.empty_item
的 parent 布局是 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;
希望这会有所帮助!
我正在开发一个 Android 应用程序,它实现了带有 ExpandableListView 菜单的导航抽屉,在此视图中,一些元素应该有子元素,而其他元素在单击时必须执行操作,没有子元素. 我的问题是我有一些随机崩溃,我不明白是什么导致了它。这是错误代码:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.toptainer.www, PID: 9722 java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setText(java.lang.CharSequence)' on a null object reference at com.example.nignog.toptainer.ExpandableListAdapter.getChildView(Success.java:377)
单击空组然后单击具有 children 的组时,应用程序通常会崩溃,但它不会总是使应用程序崩溃。
无论如何这是我的代码:
首先这是我的适配器:
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;
}
}
Activity的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);
}
如有任何帮助,我们将不胜感激。
在你的getChildView()
TextView txtListChild = (TextView) convertView.findViewById(R.id.textoOpcion);
txtListChild
是 null
不知何故。这就是为什么你得到 NullPointerException
.
Why ?
原因是你在为不同的情况膨胀不同的布局 -
R.layout.menu_item
组 children 和
R.layout.empty_item
没有 child
但只有在
时你才会膨胀视图if (convertView == null)
在这种情况下,假设最后一个膨胀的视图是 R.layout.empty_item
,如果下一个项目是没有 child 的组,则
if (convertView == null)
将 return 为假,因此您的 R.layout.menu_item
不会被夸大,它会重复使用 R.layout.empty_item
。在这种情况下,您将不会拥有 textView
(将为空)。这会给你 NullPointerException。
Solution
您必须通过使它们的 parent 布局不同来更改这 2 个布局。
假设 R.layout.empty_item
的 parent 布局是 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;
希望这会有所帮助!