Search code examples
androidhashmapexpandablelistviewkeyset

Application stops when clicked on item in ExpandableListview Android


I'm trying to create an ExpandableListView, below is my code for creating data for the expandable list

DBHelper dbHelper;
ExpandableListAdapter listAdapter;
ExpandableListView expListView;
HashMap<String, List<String>> hashDataChild;
ArrayList<DetailsOfLocation> arrayList;

public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

expListView = (ExpandableListView) v.findViewById(R.id.lvExp); // get the listview
initializeDatabase();
        prepareChildData();

listAdapter = new ExpandListAdapter(getActivity(), arrayList, hashDataChild);
        expListView.setAdapter(listAdapter);

return v;
}

public void initializeDatabase()
{
    dbHelper = new DBHelper(getActivity());

    try {
        dbHelper.createDataBase();
    } catch (IOException ioe) {
        throw new Error("Unable to create database");
    }

    try {
        dbHelper.openDataBase();
    } catch (SQLException sqle) {
        throw sqle;
    }
}

private void  prepareChildData(){
    hashDataChild = new HashMap<String, List<String>>();

//arrayList has a multiple column in it where it will be displayed as the header. The data is from the database

    Integer id = ((MyApplication) getActivity().getApplication()).getID();
    arrayList = new ArrayList<DetailsOfLocation>();
    arrayList = dbHelper.getList(id);

 //child is the child's data
    List<String> child = new ArrayList<String>();
    child.add("Other Info");
    child.add("Picture");
    child.add("Contact");

//the header and child is being inserted
    for(DetailsOfLocation list : arrayList){
            hashDataChild.put(String.valueOf(list), child);
        }
    }
}

When I'm debugging it, the hashDataChild has the values of what I'm expecting to have where each header has 3 child in it. But when trying on my phone it crashes and it doesn't show anything in logcat. The reference I'm using for creating an expandable listview is [this]:http://www.androidhive.info/2013/07/android-expandable-list-view-tutorial/

I was thinking that it might be because the ExpandableListview OnGroupClickListener is not working? How can I solve this? It goes inside my onGroupClick but doesn't show the list of child

 // Listview Group click listener
        expListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
            @Override
            public boolean onGroupClick(ExpandableListView parent, View v,
                                        int groupPosition, long id) {
                Toast.makeText(
                        getActivity().getApplicationContext(),
                        arrayList.get(groupPosition)
                                + " : "
                                + hashDataChild.get(
                                arrayList.get(groupPosition)), Toast.LENGTH_SHORT)
                        .show();

                return false;
            }
        });

Below is my code for my Expandable Adapter

public class ExpandListAdapter extends BaseExpandableListAdapter {

private Context _context;
private ArrayList<DetailsOfLocation> mDetailsWithNoLocation;
private HashMap<String, List<String>> mchildOfDetailsWithNoLocation; 

public ExpandListAdapter(Context context, ArrayList<DetailsOfLocation> detailsWithNoLocation, HashMap<String, List<String>> HashChildData) {
    this._context = context;
    this.mDetailsWithNoLocation = detailsWithNoLocation; //header
    this.mchildOfDetailsWithNoLocation = HashChildData; //hash data
}


@Override
public Object getChild(int groupPosition, int childPosititon) {
    return this.mchildOfDetailsWithNoLocation.get(this.mDetailsWithNoLocation.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) {

    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.expandlist_child_item, null);
    }

    TextView txtListChild = (TextView) convertView
            .findViewById(R.id.tvother_info);

    txtListChild.setText(childText);
    return convertView;
}

@Override
public int getChildrenCount(int groupPosition) {
    return this.mchildOfDetailsWithNoLocation.get(this.mDetailsWithNoLocation.get(groupPosition))
            .size();
}


@Override
public Object getGroup(int groupPosition) {
    return this.mDetailsWithNoLocation.get(groupPosition);
}

@Override
public int getGroupCount() {
    return mDetailsWithNoLocation.size();
}

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

@Override
public View getGroupView(int groupPosition, boolean isExpanded,
                         View convertView, ViewGroup parent) {


    if (convertView == null) {
        LayoutInflater infalInflater = (LayoutInflater) this._context
                .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        convertView = infalInflater.inflate(R.layout.expandlist_group_item, null);
    }

    TextView lblListDesc = (TextView) convertView.findViewById(R.id.tv_desc);
    TextView lblListRoom = (TextView) convertView.findViewById(R.id.tv_location);
    TextView lblListAudience = (TextView) convertView.findViewById(R.id.tv_audience);
    TextView lblListSpeaker = (TextView) convertView.findViewById(R.id.tv_speaker);


    DetailsOfLocation noLocationobj = mDetailsWithNoLocation.get(groupPosition);

    lblListDesc.setText(noLocationobj.getDesc());
    lblListRoom.setText("Room: "+noLocationobj.getLocation());
    lblListAudience.setText("Audience: "+noLocationobj.getAudience());
    lblListSpeaker.setText("Speaker/s: "+noLocationobj.getSpeaker());


    return convertView;
}

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

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

}

Thank you so much for the help.


Update

I have tried returning true in my onGroupClick() and hashDataChild.get( arrayList.get(groupPosition)) is null why is it like that even if when checking the arrayList it has value?


i think i found the reason why using this

if(!hashDataChild.containsKey(arrayList))

my hashDataChild doesn't contain key i don't know why and how to solve it any ideas why it is like that? even if when I'm debugging it does shows its keys and value of my arrayList?


I've change the containsKey and used String.valueOf(arrayList.get(groupPosition)) as suggested. But my child data still doesn't show up and return false in onGroupClick() it still closes my application.


Solution

  • Okay, i've tried your code and the click is causing NullPointerException, you miss the String.valueOf() in every call of your mDetailsWithNoLocation, Change these two method in your adapter

    @Override
    public int getChildrenCount(int groupPosition) {
        return this.mchildOfDetailsWithNoLocation.get(String.valueOf(
                this.mDetailsWithNoLocation.get(groupPosition))).size();
    }
    
    @Override
    public Object getChild(int groupPosition, int childPosititon) {
        return this.mchildOfDetailsWithNoLocation.get(String.valueOf(
                this.mDetailsWithNoLocation.get(groupPosition))).get(
                childPosititon);
    }
    

    Should have work now.. notes: you should also post you activity code in your question, to make other people easier to test your code. I need to do some guessing to test this.. :)