This tutorial shows how to display a HashMap with String and ArrayList<String> as key value pairs, in an ExpandableListView.
Step 1: Create a new project with name ExpandableListView and package name com.myexample.listview. Select File/New/New Project. Fill the forms and click “Finish” button.
Step 2: Open res/layout/xml (or) main.xml and add following code. Here we add an ExpandableListView mainListview1.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:ads="http://schemas.android.com/apk/res-auto" tools:context=".MainActivity" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ExpandableListView android:layout_height="wrap_content" android:layout_width="wrap_content" android:id="@+id/mainListview1"/> </LinearLayout>
Step 4: In res/layout/ directory add a new file header_item.xml and add following code. Here we add a TextView for displaying the headers of lists.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:background="#990048"> <TextView android:layout_height="wrap_content" android:layout_width="match_parent" android:text="Large Text" android:id="@+id/listitemTextView1" android:padding="8dp" android:textSize="16sp" android:textColor="#FCFCFC" android:textStyle="bold"/> </LinearLayout>
Step 4: In res/layout/ directory add another file child_item.xml and add following code. Here we add a TextView for displaying the children in each list.
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical" android:padding="10dp"> <TextView android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceMedium" android:layout_width="match_parent" android:text="Medium Text" android:textColor="#C00B00" android:id="@+id/childitemTextView1"/> </LinearLayout>
Step 5: Open app/src/main/java/package and open MainActivity.java. Add following code in it.
package com.myexample.listview; import android.app.*; import android.os.*; import android.view.*; import android.view.View.*; import android.widget.*; import java.util.*; import android.content.*; public class MainActivity extends Activity { private ExpandableListView listview1; // Create a HashMap for all groups and their items private HashMap<String, ArrayList<String>> allGroups = new HashMap<>(); // Create a list for all group headings ArrayList<String> allheadings; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listview1 = (ExpandableListView) findViewById(R.id.mainListview1); // Toast item title when ListView item is clicked listview1.setOnChildClickListener(new ExpandableListView.OnChildClickListener(){ @Override public boolean onChildClick(ExpandableListView listview, View child, int groupposition, int childposition, long position){ Toast.makeText(getApplicationContext(), allGroups.get(allheadings.get(groupposition)).get(childposition), Toast.LENGTH_LONG).show(); return true; } }); // Create a separate list for each group, and add items to them ArrayList<String> group1items = new ArrayList<>(); group1items.add("Group 1 item 1"); group1items.add("Group 1 item 2"); group1items.add("Group 1 item 3"); group1items.add("Group 1 item 4"); group1items.add("Group 1 item 5"); ArrayList<String> group2items = new ArrayList<>(); group2items.add("Group 2 item 1"); group2items.add("Group 2 item 2"); group2items.add("Group 2 item 3"); group2items.add("Group 2 item 4"); ArrayList<String> group3items = new ArrayList<>(); group3items.add("Group 3 item 1"); group3items.add("Group 3 item 2"); group3items.add("Group 3 item 3"); group3items.add("Group 3 item 4"); group3items.add("Group 3 item 5"); ArrayList<String> group4items = new ArrayList<>(); group4items.add("Group 4 item 1"); group4items.add("Group 4 item 2"); group4items.add("Group 4 item 3"); // put the lists created above in the HashMap allGroups, with separate keys allGroups.put("This is Group 1", group1items); allGroups.put("This is Group 2", group2items); allGroups.put("This is Group 3", group3items); allGroups.put("This is Group 4", group4items); // Add all keys in HashMap allGroups to List String allheadings allheadings = new ArrayList<String>(allGroups.keySet()); // Create a new CustomListAdapter and set it as adapter of ExpandableListView CustomListAdapter adapter = new CustomListAdapter(this, allGroups, allheadings); listview1.setAdapter(adapter); ((BaseAdapter)listview1.getAdapter()).notifyDataSetChanged(); } public class CustomListAdapter extends BaseExpandableListAdapter { private Context context; HashMap<String, ArrayList<String>> groups; ArrayList<String> headings; // Public constructor public CustomListAdapter(Context context, HashMap<String, ArrayList<String>> groups, ArrayList<String> headings) { this.context = context; this.groups = groups; this.headings = headings; } @Override public int getGroupCount() { // Return total number of groups return headings.size(); } @Override public int getChildrenCount(int position) { // Return total items in each group return groups.get(headings.get(position)).size(); } @Override public Object getGroup(int position) { // Return group heading return headings.get(position); } @Override public Object getChild(int groupposition, int childposition) { // Return child from specified group at the specified position return groups.get(headings.get(groupposition)).get(childposition); } @Override public long getGroupId(int position) { return position; } @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){ View v = convertView; // Inflate the layout for each list row LayoutInflater _inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (v == null) { v = _inflater.inflate(R.layout.header_item, null); } // Set Width of ListView to MATCH_PARENT parent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); // Get the TextView from CustomView for displaying group headings TextView txtview = (TextView) v.findViewById(R.id.listitemTextView1); // Set the text and image for current item using data from map list txtview.setText(headings.get(groupPosition)); // Return the view for the current row return v; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent){ View v = convertView; // Inflate the layout for each list row LayoutInflater _inflater = (LayoutInflater)getBaseContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE); if (v == null) { v = _inflater.inflate(R.layout.child_item, null); } // Set Width of ListView to MATCH_PARENT parent.setLayoutParams(new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.WRAP_CONTENT)); // Get the TextView from CustomView for displaying children TextView txtview = (TextView) v.findViewById(R.id.childitemTextView1); // Set the text for current item using data from map list txtview.setText((groups.get(headings.get(groupPosition))).get(childPosition)); // Return the view for the current row return v; } @Override public boolean isChildSelectable(int groupposition, int childposition) { return true; } } }
Output:
Now run the app. The app will display a ExpandableListView.