Search code examples
androidjsonadapterexpandablelistviewjsonparser

Dynamic Expandable Listview Issue


I am trying to implement dynamic values in expandable listview but facing an issue while adding the subitems in each main item. The problem is all the subitems gets added to each main item rather than getting added to their respective main item. Here is the initialization of the ArrayList I am using-

 DayBookAdapter adapter;
    ArrayList<ArrayList<DayBookDetailsData>> ch_list = new ArrayList<ArrayList<DayBookDetailsData>>();

    ArrayList<DayBookData> list = new ArrayList<>(); 

Here is the code of JSON parsing and adding the main item and subitem-

 try
        {
            JSONObject jsonrootobjct=new JSONObject(response);
            JSONArray jsonArray = null;
            jsonArray=jsonrootobjct.getJSONArray("data");

            for (int i = 0; i < jsonArray.length(); i++) {

                JSONObject jsonObject1 = null;
                jsonObject1= jsonArray.getJSONObject(i);
                try {
                    category_id = jsonObject1.getString(Json_categoryid);
                    category_name = jsonObject1.getString(Json_categoryname);

                    JSONArray jsonArrayitem=null;
                    jsonArrayitem = jsonObject1.getJSONArray("itemdata");
                    for (int j = 0; j < jsonArrayitem.length(); j++) {
                        jsonObject1 = jsonArrayitem.getJSONObject(j);
                        try {
                            item_name = jsonObject1.getString(Json_itemname);
                            item_id = jsonObject1.getString(Json_itemid);
                            DayBookDetailsData ch = new DayBookDetailsData(item_name, item_id);
                            ch_list.add(ch);
                        }
                        catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }

                    DayBookData gru = new DayBookData(category_id,category_name, ch_list);
                    list.add(gru);
                    adapter=new DayBookAdapter(getApplicationContext(), list);
                    exp_listview.setAdapter(adapter);

                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }

        }
        catch (JSONException e)
        {
            e.printStackTrace();
        }

This is my DayBookData code-

public class DayBookData {


    private String category_name;
    private String category_id;
    private ArrayList<DayBookDetailsData> ch_list;

    public String getCategory_id() {
        return category_id;
    }

    public String getCategory_name() {
        return category_name;
    }

    public ArrayList<DayBookDetailsData> getCh_list() {
        return ch_list;
    }

    public DayBookData(String category_id, String category_name, ArrayList<DayBookDetailsData> ch_list) {
        this.category_id=category_id;
        this.category_name=category_name;
        this.ch_list=ch_list;
    }

    public ArrayList<DayBookDetailsData> getItems() {
        return ch_list;
    }
}

This is my DayBookDetailsData code -

public class DayBookDetailsData {


    String item_name;
    String item_id;


    public String getItem_name() {
        return item_name;
    }

    public String getItem_id() {
        return item_id;
    }



    public DayBookDetailsData( String item_name, String item_id) {
        this.item_name=item_name;
        this.item_id=item_id;

    }
}

My DaybookAdapter code is -

public class DayBookAdapter  extends BaseExpandableListAdapter {

    private Context c;
    private ArrayList<DayBookData> list;
    private LayoutInflater inflater;

    public DayBookAdapter(Context c, ArrayList<DayBookData> list)
    {
        this.c=c;
        this.list=list;
        inflater=(LayoutInflater ) c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    }

    @Override
    public int getGroupCount() {
        // TODO Auto-generated method stub
        //return team.size();
        return list.size();
    }
    @Override
    public int getChildrenCount( int listPosition) {
        // TODO Auto-generated method stub
        //return team.get(groupPosw).players.size();
      ArrayList<DayBookDetailsData> chList = list.get(listPosition).getItems();
        return chList.size();
    }

    @Override
    public Object getGroup(int listPosition) {
        // TODO Auto-generated method stub
        //return team.get(groupPos);
        return list.get(listPosition);
    }

    @Override
    public Object getChild(int listPosition, int expandedListPosition) {
        // TODO Auto-generated method stub
        //return team.get(groupPos).players.get(childPos);

        ArrayList<DayBookDetailsData> chList =  list.get(listPosition).getItems();
        return chList.get(expandedListPosition);
    }

    @Override
    public long getGroupId(int listPosition) {
        // TODO Auto-generated method stub
        //return 0;
        return listPosition;
    }

    @Override
    public long getChildId(int listPosition, int expandedListPosition) {
        // TODO Auto-generated method stub
        //return 0;
        return expandedListPosition;
    }

    @Override
    public boolean hasStableIds() {
        // TODO Auto-generated method stub
        return true;
    }

    @Override
    public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        DayBookData group = (DayBookData) getGroup(listPosition);
        if (convertView == null) {
            LayoutInflater layoutInflater = (LayoutInflater) c
                    .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.day_book_data_item,null);
        }

        TextView category_id=(TextView) convertView.findViewById(R.id.category_id);
        TextView category_name=(TextView) convertView.findViewById(R.id.category_name);
        category_id.setText(group.getCategory_id());
        category_name.setText(group.getCategory_name());
        return convertView;
    }

    @Override
    public View getChildView(int listPosition, int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) {
        if(expandedListPosition ==0)
        {
           convertView = inflater.inflate(R.layout.child_header, null);
            //TextView txtHeader = (TextView)convertView.findViewById(R.id.txtHeader);
            //txtHeader.setText("Hello");

        }
        if(expandedListPosition>0 && expandedListPosition<getChildrenCount(listPosition)-1) {

            DayBookDetailsData child = (DayBookDetailsData) getChild(listPosition, expandedListPosition);
            LayoutInflater layoutInflater = (LayoutInflater) this.c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = layoutInflater.inflate(R.layout.day_book_details_data_item, null);
            TextView item_name = (TextView) convertView.findViewById(R.id.item_name);
            TextView item_id = (TextView) convertView.findViewById(R.id.item_id);
            item_name.setText(child.getItem_name());
            item_id.setText(child.getItem_id());
        }

        return convertView;
    }

    @Override
    public boolean isChildSelectable(int arg0, int arg1) {
        // TODO Auto-generated method stub
        return true;
    }
}

And my JSON Data looks like this -

"data":[
{
"c_name":"Stage And Platform",
"cat_id":"29",
"itemdata":[
{
"id":"2",
"item":" Wooden Stage"
},
{
"id":"3",
"item":" Iron Stage"
},
{
"id":"4",
"item":"Round Stage"
},
{
"id":"5",
"item":" Rotating Stage"
},
{
"id":"6",
"item":" Hydraulic Stage"
},
{
"id":"7",
"item":"Hydro-Rotating Stage"
},
{
"id":"8",
"item":"Wooden Dance Floor"
},
{
"id":"9",
"item":"Acrylic Dance Floor"
},
{
"id":"10",
"item":"Led Dance Floor"
},
{
"id":"466",
"item":"Podium"
}
]
},
{
"c_name":" Bar Set Up",
"cat_id":"30",
"itemdata":[
{
"id":"11",
"item":"Bar Chair"
},
{
"id":"12",
"item":"Bar Table"
},
{
"id":"13",
"item":"Bar Counter Wooden "
},
{
"id":"14",
"item":" Acrylic Bar Counter "
},
{
"id":"15",
"item":"Led Bar Counter"
},
{
"id":"16",
"item":"Bartender"
},
{
"id":"17",
"item":"Bar Utensils"
},
{
"id":"18",
"item":"Glass Bar Table"
}
]
}

Please help. Thank you in advance.


Solution

  • I just checked your code, you are using some wrong way to parse your json and bind ExpandableListView using adapter.

    I have corrected some code and now it's working fine. Please check below code.

    Json Parsing method

    public void parseJsonData(String response) {
    
        try {
    
            ArrayList<DayBookData> listData = new ArrayList<>();
    
            JSONObject jObjMain = new JSONObject(response);
            JSONArray jArrData = jObjMain.getJSONArray("data");
    
            for (int i = 0; i < jArrData.length(); i++) {
    
                DayBookData bData = new DayBookData();
    
                JSONObject jObjIn = new JSONObject(jArrData.getString(i));
    
                bData.setCategory_id(jObjIn.getString("cat_id"));
                bData.setCategory_name(jObjIn.getString("c_name"));
    
                JSONArray jArrItemData = new JSONArray(jObjIn.getString("itemdata"));
    
                for (int j = 0; j < jArrItemData.length(); j++) {
    
                    JSONObject jObjItem = new JSONObject(jArrItemData.getString(j));
    
                    try {
    
                        String item_id = jObjItem.getString("id");
                        String item_name = jObjItem.getString("item");
    
                        bData.getCh_list().add(new DayBookDetailsData(item_name, item_id));
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
    
                listData.add(bData);
            }
    
            exp_listview.setAdapter(new DayBookAdapter(context, listData));
    
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }
    

    DayBookData.java

    public class DayBookData {
    
        private String category_name;
        private String category_id;
        private ArrayList<DayBookDetailsData> ch_list;
    
        public DayBookData() {
            this.category_id = "";
            this.category_name = "";
            this.ch_list = new ArrayList<>();
        }
    
        public String getCategory_name() {
            return category_name;
        }
    
        public void setCategory_name(String category_name) {
            this.category_name = category_name;
        }
    
        public String getCategory_id() {
            return category_id;
        }
    
        public void setCategory_id(String category_id) {
            this.category_id = category_id;
        }
    
        public ArrayList<DayBookDetailsData> getCh_list() {
            return ch_list;
        }
    
        public void setCh_list(ArrayList<DayBookDetailsData> ch_list) {
            this.ch_list = ch_list;
        }
    }
    

    DayBookDetailsData.java

    public class DayBookDetailsData {
    
        private String item_name;
        private String item_id;
    
        public DayBookDetailsData(String item_name, String item_id) {
            this.item_name = item_name;
            this.item_id = item_id;
        }
    
        public String getItem_name() {
            return item_name;
        }
    
        public String getItem_id() {
            return item_id;
        }
    }
    

    DatBookAdapter.java

    public class DayBookAdapter extends BaseExpandableListAdapter {
    
        private Context _context;
        private List<DayBookData> listDataHeader;
    
        public DayBookAdapter(Context context, List<DayBookData> listDataHeader) {
            this._context = context;
            this.listDataHeader = listDataHeader;
        }
    
        @Override
        public ArrayList<DayBookDetailsData> getChild(int groupPosition, int childPosititon) {
            return this.listDataHeader.get(groupPosition).getCh_list();
        }
    
        @Override
        public long getChildId(int groupPosition, int childPosition) {
            return childPosition;
        }
    
        @SuppressLint("InflateParams")
        @Override
        public View getChildView(int groupPosition, final int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
    
            final DayBookDetailsData childText = listDataHeader.get(groupPosition).getCh_list().get(childPosition);
    
            if (convertView == null) {
                LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = infalInflater.inflate(R.layout.item_day_book_data, null);
            }
    
            TextView item_txt_sub_cat_id = convertView.findViewById(R.id.item_txt_sub_cat_id);
            item_txt_sub_cat_id.setText(childText.getItem_id());
    
            TextView item_txt_sub_cat_name = convertView.findViewById(R.id.item_txt_sub_cat_name);
            item_txt_sub_cat_name.setText(childText.getItem_name());
    
            return convertView;
        }
    
        @Override
        public int getChildrenCount(int groupPosition) {
            return this.listDataHeader.get(groupPosition).getCh_list().size();
        }
    
        @Override
        public DayBookData getGroup(int groupPosition) {
            return this.listDataHeader.get(groupPosition);
        }
    
        @Override
        public int getGroupCount() {
            return this.listDataHeader.size();
        }
    
        @Override
        public long getGroupId(int groupPosition) {
            return groupPosition;
        }
    
        @SuppressLint("InflateParams")
        @Override
        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
    
            DayBookData headerTitle = getGroup(groupPosition);
    
            if (convertView == null) {
                LayoutInflater infalInflater = (LayoutInflater) this._context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = infalInflater.inflate(R.layout.item_day_book_header, null);
            }
    
            TextView item_txt_category_id = convertView.findViewById(R.id.item_txt_category_id);
            TextView item_txt_category_name = convertView.findViewById(R.id.item_txt_category_name);
    
            item_txt_category_id.setText(headerTitle.getCategory_id());
            item_txt_category_name.setText(headerTitle.getCategory_name());
    
            return convertView;
        }
    
        @Override
        public boolean hasStableIds() {
            return false;
        }
    
        @Override
        public boolean isChildSelectable(int groupPosition, int childPosition) {
            return true;
        }
    }
    

    You can bind below listeners to get and track your click for both Header and Child item.

    Child Item Click Listener

    exp_listview.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
    
        @Override
        public boolean onChildClick(ExpandableListView expandableListView, View view, int groupPosition, int childPosition, long l) {
    
            DayBookDetailsData mItem = listData.get(groupPosition).getListInnerMenu().get(childPosition);
    
            // You can get your listView child click event and data here.
    
            return false;
        }
    });
    

    Header Item Click Listener

    exp_listview.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() {
    
        @Override
        public boolean onGroupClick(ExpandableListView expandableListView, View view, int position, long l) {
    
            DayBookData mItem = listData.get(position);
    
            // You can get your listView header click event and data here.
    
            return false;
        }
    });
    

    Please try this code. It might work for you.