Reputation: 25
I'm working on an Android app which implements a navigation drawer with an ExpandableListView menu, in this view some elements are supposed to have childs and others have to do an action when clicked, with no childs. My problem here is that I have some random crashing and I can't understand what may be causing it. Here's the error code:
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)
App will mostly crash when clicking an empty group and then clicking on a group with children, though it won't always crash the app.
Anyway here's my code:
First of all here's my adapter:
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's onCreate method:
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;
}
});
And here is my prepareData method:
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);
}
Any help woud be greatly appreciated.
Upvotes: 1
Views: 1364
Reputation: 7070
In your getChildView()
TextView txtListChild = (TextView) convertView.findViewById(R.id.textoOpcion);
txtListChild
is null
somehow. That's why you are getting NullPointerException
.
Why ?
The reason is that you are inflating different layouts for different situations -
R.layout.menu_item
for group with children and
R.layout.empty_item
view for group having no child
but you are inflating the view only if
if (convertView == null)
and in that case suppose the last view inflated is R.layout.empty_item
and if the next item is group with no child, the
if (convertView == null)
will return false and hence your R.layout.menu_item
will not be inflated and it will reuse R.layout.empty_item
. And in that case you will not have your textView
(which will be null). This will give you NullPointerException.
Solution
You have to change the 2 layouts by making their parent layout different.
Let's say the parent layout for R.layout.empty_item
is RelativeLayout
and for R.layout.menu_item
is LinearLayout
.
Change your 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;
Hope this will help !
Upvotes: 2