Populate Expandable ListView with SQLite database error

282 Views Asked by At

I'm new in android development. I'm using a Expandable listvew to display the places from my database and I'm extending BaseExpandableListAdapter but It seems to force close and give error that I have added below.

Adapter Class

package com.example.project.Adapters;

import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.TextView;

import com.example.project.R;

import java.util.HashMap;
import java.util.List;

public class Expandable_List_Adapter extends BaseExpandableListAdapter {
    private Context context;
    private List<String> listDataHeader;
    private HashMap<String,List<String>> _listDataChild;

    public Expandable_List_Adapter(Context context, List<String> listDataHeader, HashMap<String, List<String>> _listDataChild) {
        this.context = context;
        this.listDataHeader = listDataHeader;
        this._listDataChild = _listDataChild;
    }


    @Override
    public int getGroupCount() {
        return this.listDataHeader.size();
    }
    @Override
    public int getChildrenCount(int groupPosition) {
        return this._listDataChild.get(this.listDataHeader.get(groupPosition)).size();
    }
    @Override
    public Object getGroup(int groupPosition) {
        return this.listDataHeader.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return this._listDataChild.get(this.listDataHeader.get(groupPosition)).get(childPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }


    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    @Override
    public boolean hasStableIds() {
        return false;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        String headerTitle=(String) getGroup(groupPosition);
        if (convertView==null){
            LayoutInflater layoutInflater=(LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView=layoutInflater.inflate(R.layout.expand_header,null);
        }
        TextView txtListH=convertView.findViewById(R.id.expand_list_items);
        txtListH.setText(headerTitle);
         return  convertView;
    }

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        final String childText =(String) getChild(groupPosition,childPosition);
        if(convertView == null){
            LayoutInflater layoutInflater=(LayoutInflater) this.context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView=layoutInflater.inflate(R.layout.expand_list_items,null);
        }
        TextView txtListCh=convertView.findViewById(R.id.expand_list_items);
        txtListCh.setText(childText);
        return  convertView;
    }

    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }
}

This is my database class which shows the places

public String display_spinner(){
        List<String> placeList=new ArrayList<>();
        db=this.getReadableDatabase();
        Cursor c=db.rawQuery("Select "+COL_PLACE_NAME+" from "+TABLE_PLACE,null);
        if(c.moveToFirst()){
            do{
                placeList.add(c.getString(0));
            }while(c.moveToNext());
        }
        c.close();
        db.close();
        return placeList.toString();
    }

And here is the implementation of the expanable view in my AddPlaceActivity

 public class AddPlaceActivity extends Activity {
 @Override
    protected void onCreate(Bundle savedInstanceState) {
expandableListView=findViewById(R.id.exp);
        expandableListAdapter=new Expandable_List_Adapter(this,listData_H,listData_Ch);
        getReady();
        expandableListView.setAdapter(expandableListAdapter);
    }
public  void getReady(){
        listData_H=new ArrayList<>();
        listData_Ch=new HashMap<String,List<String>>();
        listData_H.add("Subjects");
        List<String> subjects=new ArrayList<>();
        subjects.add(databaseSubject.display_spinner());
    }

Here is the LOGCAT ERROR

Caused by: java.lang.NullPointerException: Attempt to invoke interface method 'int java.util.List.size()' on a null object reference
        at com.example.project.Adapters.Expandable_List_Adapter.getGroupCount(Expandable_List_Adapter.java:29)
        at android.widget.ExpandableListConnector.getCount(ExpandableListConnector.java:397)
        at android.widget.ListView.setAdapter(ListView.java:614)
        at android.widget.ExpandableListView.setAdapter(ExpandableListView.java:601)
        at com.example.project.AddStudentActivity.onCreate(AddStudentActivity.java:162)
        at android.app.Activity.performCreate(Activity.java:7335)
        at android.app.Activity.performCreate(Activity.java:7326)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1275)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3119)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3282) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:78) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:108) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:68) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1970) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loop(Looper.java:214) 
        at android.app.ActivityThread.main(ActivityThread.java:7156) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:975) 
2

There are 2 best solutions below

2
pappbence96 On

In your AddPlaceActivity.OnCreate you seem to be creating the adapter before initializing the lists:

//You use the list here
expandableListAdapter=new Expandable_List_Adapter(this,listData_H,listData_Ch);
//You initialize the list here, AFTER using it
getReady();

Try switching the order of these two lines.

0
Wilson Sim On

Your problem is here :

expandableListAdapter=new Expandable_List_Adapter(this,listData_H,listData_Ch);
getReady();

You are trying to set the listData_H this variable to your adapter before it is initialized in your getReady();

listData_H=new ArrayList<>(); should be executed first before doing expandableListAdapter=new Expandable_List_Adapter(this,listData_H,listData_Ch);

or else you will be getting NullPointerException. Hope it helps.