Android Expandable Listview :
Android Expandable Listview name itself says that it will be expanded depending upon categories.
Generally when we deal with menu’s which are to be show in listview, Sometimes we need to show sub-categories so for this purpose we will deal with.
In almost every app expandable listview in android, where there is a category there we can find these expandable listview, like new apps TOI, Hindu, swiggy, zomato and many other food delivery apps use these kinds of list’s to make the user interface much better.
Almost these list can be dynamically populated from json array’s a lot of information can be stored and populated on demand making the efficient use of screen space available and avoiding inconvenience.
Android Expandable Listview is the finest way to publish data to the users i.e., in categorical way such that it it easy to understand and represent too with the help of this blog.
Categories are shown as group headers and sub categories are shown as child items in expandable listview.
I have shown a Android Expandable Listview example which contains three categories
- Sports
- Colors
- Animals
Which are further sub categorized for example:
Android Expandable Listview Code :
Creating android ExpandableListviewAdapter File for Android Expandable Listview
ExpandableListAdapter.java :
Here we use a traditional way to bind the views you may use databinding too.
In this Adapter we are fully concentrating on child view populating data and onClickListener’s as we have considered group’s Click listeners in MainActivity.
public class ExpandableListAdapter extends BaseExpandableListAdapter { private Context context; private List<String> ParentItem; private HashMap<String, List<String>> ChildItem; public ExpandableListAdapter(Context context, List<String> ParentItem, HashMap<String, List<String>> ChildItem) { this.context = context; this.ParentItem = ParentItem; this.ChildItem = ChildItem; } @Override public Object getChild(int listPosition, int expandedListPosition) { return this.ChildItem.get(this.ParentItem.get(listPosition)) .get(expandedListPosition); } @Override public long getChildId(int listPosition, int expandedListPosition) { return expandedListPosition; } @Override public View getChildView(int listPosition, final int expandedListPosition, boolean isLastChild, View convertView, ViewGroup parent) { final String expandedListText = (String) getChild(listPosition, expandedListPosition); if (convertView == null) { LayoutInflater layoutInflater = (LayoutInflater) this.context .getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.child_item, null); } TextView text1 = (TextView) convertView.findViewById(R.id.item1); TextView text2 = (TextView) convertView.findViewById(R.id.item2); text1.setText(""+expandedListPosition); text2.setText(""+expandedListText); return convertView; } @Override public int getChildrenCount(int listPosition) { return this.ChildItem.get(this.ParentItem.get(listPosition)) .size(); } @Override public Object getGroup(int listPosition) { return this.ParentItem.get(listPosition); } @Override public int getGroupCount() { return this.ParentItem.size(); } @Override public long getGroupId(int listPosition) { return listPosition; } @Override public View getGroupView(int listPosition, boolean isExpanded, View convertView, ViewGroup parent) { String listTitle = (String) getGroup(listPosition); if (convertView == null) { LayoutInflater layoutInflater = (LayoutInflater) this.context. getSystemService(Context.LAYOUT_INFLATER_SERVICE); convertView = layoutInflater.inflate(R.layout.parent_item, null); } TextView listTitleTextView = (TextView) convertView .findViewById(R.id.listTitle); listTitleTextView.setTypeface(null, Typeface.BOLD); listTitleTextView.setText(listTitle); return convertView; } @Override public boolean hasStableIds() { return false; } @Override public boolean isChildSelectable(int listPosition, int expandedListPosition) { return true; } public static HashMap<String, List<String>> getData() { HashMap<String, List<String>> ParentItem = new HashMap<String, List<String>>(); List<String> Colors = new ArrayList<String>(); Colors.add("Red"); Colors.add("Green"); Colors.add("Blue"); Colors.add("Maroon"); Colors.add("Yellow"); Colors.add("Violet"); Colors.add("Pink"); List<String> Animals = new ArrayList<String>(); Animals.add("Lion"); Animals.add("Tiger"); Animals.add("Leopard"); Animals.add("Cheetah"); Animals.add("Bear"); List<String> Sports = new ArrayList<String>(); Sports.add("Cricket"); Sports.add("Football"); Sports.add("Tennis"); Sports.add("Basket Ball"); Sports.add("Base Ball"); ParentItem.put("Colors", Colors); ParentItem.put("Animals", Animals); ParentItem.put("Sports", Sports); return ParentItem; } }
Assigning expandableListView set onClickListener for group click and child click.
MainActivity.java :
We need to take care of Group click listener and then after the group expansion we need to make sure of the child click listeners too.
public class MainActivity extends Activity { ExpandableListView expandableListView; ExpandableListAdapter expandableListAdapter; List<String> expandableListTitle; HashMap<String, List<String>> expandableListDetail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); expandableListView = (ExpandableListView) findViewById(R.id.expandableListView); expandableListDetail = ExpandableListAdapter.getData(); expandableListTitle = new ArrayList<String>(expandableListDetail.keySet()); expandableListAdapter = new ExpandableListAdapter(this, expandableListTitle, expandableListDetail); expandableListView.setAdapter(expandableListAdapter); expandableListView.setOnGroupExpandListener(new OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { Toast.makeText(getApplicationContext(), expandableListTitle.get(groupPosition) + " ListView Open.", Toast.LENGTH_SHORT).show(); } }); expandableListView.setOnGroupCollapseListener(new OnGroupCollapseListener() { @Override public void onGroupCollapse(int groupPosition) { Toast.makeText(getApplicationContext(), expandableListTitle.get(groupPosition) + " ListView Closed.", Toast.LENGTH_SHORT).show(); } }); expandableListView.setOnChildClickListener(new OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Toast.makeText(getApplicationContext(), expandableListDetail.get( expandableListTitle.get(groupPosition)).get( childPosition), Toast.LENGTH_SHORT ) .show(); return false; } }); } }
activity_main.xml :
Adding ExpandableListView to activity_main.xml.
Here we are making use of a ExpandableListView to make sure our list data is loaded with expansion and compression view
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" android:paddingBottom="@dimen/activity_vertical_margin"> <ExpandableListView android:id="@+id/expandableListView" android:layout_height="match_parent" android:layout_width="match_parent" android:indicatorLeft="?android:attr/expandableListPreferredItemIndicatorLeft" android:divider="#A4C739" android:dividerHeight="1dp" /> </RelativeLayout>
Adding parent (Group Header).
parent_item.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/listTitle" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="?android:attr/expandableListPreferredItemPaddingLeft" android:textColor="#ffffff" android:background="#B40404" android:paddingTop="10dp" android:paddingBottom="10dp" /> </LinearLayout>
Adding child_item to listview
child_item.xml :
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:orientation="horizontal" android:layout_width="match_parent" android:layout_height="wrap_content" android:weightSum="2" android:padding="2dp"> <TextView android:id="@+id/item1" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" android:paddingTop="10dp" android:layout_weight="1.5" android:paddingBottom="10dp" /> <TextView android:id="@+id/item2" android:layout_width="fill_parent" android:layout_height="wrap_content" android:paddingLeft="?android:attr/expandableListPreferredChildPaddingLeft" android:paddingTop="10dp" android:layout_weight="0.5" android:paddingBottom="10dp" /> </LinearLayout> </LinearLayout>
Android Expandable Listview Output :
Here finally we can see the output of Expandable Listview example.
Group and Child On Click Toast
If you have any query’s in this tutorial on Expandable Listview comment below and for more on listview’s may refer
Like and share this tutorial for more interesting updates.
View Comments (5)
thank a lot
it was useful
a question ?
when I change ParentItem.put("color",--) string, and add some items,
how to sort with an order that i want???
for example first color, second animal and so...
specify color first then animal and then so on depending upon your requirement, and also if you want to sort list in order based on alphabetical order you can use comparator for that.
Working food. thanks very helpfull.
please tell me how to add search filter in this page. thanks for beautiful tutorial
hi sorry for delay surely i will make a tutorial on search filter in expandable listview soon