我正在开发一个 Android 应用程序,它实现了一个带有 ExpandableListView 菜单的抽屉导航,在此 View 中,某些元素应该有子元素,而其他元素则必须在单击时执行操作,而没有子元素。 我的问题是,我遇到了一些随机崩溃,我不明白是什么原因造成的。这是错误代码:
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)
当单击空组然后单击包含子组的组时,应用程序大多会崩溃,但并不总是会导致应用程序崩溃。
无论如何,这是我的代码:
首先这是我的适配器:
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
对于有 child 的团体和
R.layout.empty_item
查看没有 child 的组
但是只有在以下情况下您才会夸大 View
if (convertView == null)
在这种情况下,假设最后一个 View 膨胀为 R.layout.empty_item
如果下一个项目是没有子项的组,则
if (convertView == null)
将返回 false,因此您的 R.layout.menu_item
不会充气并且会重复使用R.layout.empty_item
。在这种情况下,您将不会拥有 textView
(这将为空)。这会给你 NullPointerException。
Solution
您必须通过使两个布局的父布局不同来更改它们。
假设 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;
希望这会有所帮助!
关于java - 当某些组为空时 ExpandableListView 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36091768/