introduction
In Android development, list display is a very common form of interaction. As a special list control, ExpandableListView allows us to create lists with grouping functions. Each group can also contain multiple children, and the grouping can expand and shrink, which greatly enhances the flexibility and readability of data display. This article will introduce in detail the usage of ExpandableListView, from basic concepts to specific implementations, and then to advanced applications, to help you fully master this control.
1. ExpandableListView Basic Concept
ExpandableListView inherits from ListView and is an expandable list view provided by Android. It mainly consists of two parts: Group and Child. Each group can contain multiple children, and the user can expand or shrink the list of corresponding children by clicking on the group. This control is suitable for scenarios where data needs to be displayed in categories, such as contact lists grouped by letters, product lists grouped by categories, etc.
2. Add ExpandableListView to the layout file
First, we need to add the ExpandableListView control to the layout file. Here is a simple example:
<!-- activity_main.xml --> <LinearLayout xmlns:andro android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <ExpandableListView android: android:layout_width="match_parent" android:layout_height="match_parent" /> </LinearLayout>
In this layout we create a vertical linear layout and add an ExpandableListView to it, with both width and height set to match_parent to fill the entire parent layout.
3. Create a data model
In order to show the data of grouping and child items, we need to create the corresponding data model class. Suppose we want to show a fruit classification list, with different fruits under each category, we can create the following data model class:
// public class GroupModel { private String groupName; public GroupModel(String groupName) { = groupName; } public String getGroupName() { return groupName; } public void setGroupName(String groupName) { = groupName; } } // public class ChildModel { private String childName; public ChildModel(String childName) { = childName; } public String getChildName() { return childName; } public void setChildName(String childName) { = childName; } }
The GroupModel class is used to represent group information and contains a group name; the ChildModel class is used to represent child information and contains a child name.
4. Create an adapter
ExpandableListView requires an adapter to bind data to the view. We can inherit the BaseExpandableListAdapter class to create a custom adapter. Here is an example:
import ; import ; import ; import ; import ; import ; import ; public class MyExpandableListAdapter extends BaseExpandableListAdapter { private Context context; private List<GroupModel> groupList; private List<List<ChildModel>> childList; public MyExpandableListAdapter(Context context, List<GroupModel> groupList, List<List<ChildModel>> childList) { = context; = groupList; = childList; } @Override public int getGroupCount() { return (); } @Override public int getChildrenCount(int groupPosition) { return (groupPosition).size(); } @Override public Object getGroup(int groupPosition) { return (groupPosition); } @Override public Object getChild(int groupPosition, int childPosition) { return (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) { GroupModel groupModel = (GroupModel) getGroup(groupPosition); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) (Context.LAYOUT_INFLATER_SERVICE); convertView = (.simple_expandable_list_item_1, null); } TextView groupTextView = (.text1); (()); return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildModel childModel = (ChildModel) getChild(groupPosition, childPosition); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) (Context.LAYOUT_INFLATER_SERVICE); convertView = (.simple_list_item_1, null); } TextView childTextView = (.text1); (()); return convertView; } @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } }
In this adapter, we need to implement a series of methods:
- getGroupCount(): Returns the number of groups.
- getChildrenCount(int groupPosition): Returns the number of child items in the specified group.
- getGroup(int groupPosition): Returns the grouped object at the specified location.
- getChild(int groupPosition, int childPosition): Returns the child object at the specified position under the specified group.
- getGroupId(int groupPosition) and getChildId(int groupPosition, int childPosition): Returns the IDs of the group and the child item, respectively.
- getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent): Creates and returns a grouped view.
- getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent): Creates and returns the view of the child.
- isChildSelectable(int groupPosition, int childPosition): Specifies whether the child can be selected.
5. Use ExpandableListView in Activity
In Activity, we need to initialize the data, create an adapter, and set it to the ExpandableListView. Here is the sample code:
import ; import ; import ; import ; import ; public class MainActivity extends AppCompatActivity { private ExpandableListView expandableListView; private MyExpandableListAdapter adapter; private List<GroupModel> groupList; private List<List<ChildModel>> childList; @Override protected void onCreate(Bundle savedInstanceState) { (savedInstanceState); setContentView(.activity_main); expandableListView = findViewById(); // Initialize the data initData(); // Create an adapter adapter = new MyExpandableListAdapter(this, groupList, childList); // Set up the adapter (adapter); } private void initData() { groupList = new ArrayList<>(); childList = new ArrayList<>(); // Add grouped data GroupModel group1 = new GroupModel("Tropical Fruit"); GroupModel group2 = new GroupModel("Temperate fruit"); (group1); (group2); // Add child data for each group List<ChildModel> childList1 = new ArrayList<>(); (new ChildModel("banana")); (new ChildModel("mango")); (childList1); List<ChildModel> childList2 = new ArrayList<>(); (new ChildModel("apple")); (new ChildModel("pear")); (childList2); } }
In the onCreate method, we first get the reference to the ExpandableListView control, then call the initData method to initialize the data, then create an adapter and set it to the ExpandableListView.
6. Handle click events for grouping and child items
We can add grouping and child click event listeners to ExpandableListView to implement the corresponding interactive logic. Here is the sample code:
// Add the following code in the onCreate method(new () { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { // Handle group click events GroupModel groupModel = (GroupModel) (groupPosition); String groupName = (); // Custom logic can be added here, such as a pop-up prompt box to display the group name return false; } }); (new () { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { // Handle child click event ChildModel childModel = (ChildModel) (groupPosition, childPosition); String childName = (); // You can add custom logic here, such as jumping to the details page return false; } });
In the group click event listener, we can get the grouped object of the click and process it accordingly; in the child click event listener, we can get the child object of the click and process it accordingly.
7. Advanced Application: Custom View
In addition to using the simple layout provided by the system, we can also customize the views of grouping and child items to achieve richer interface effects. Here is an example of a custom view:
Custom group layout file group_item.xml
<LinearLayout xmlns:andro android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <ImageView android: android:layout_width="24dp" android:layout_height="24dp" android:src="@mipmap/ic_launcher" /> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:textSize="18sp" /> </LinearLayout>
Customize child layout file child_item.xml
<LinearLayout xmlns:andro android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp"> <ImageView android: android:layout_width="24dp" android:layout_height="24dp" android:src="@mipmap/ic_launcher" /> <TextView android: android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginLeft="10dp" android:textSize="16sp" /> </LinearLayout>
Modify the getGroupView and getChildView methods in the adapter
@Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { GroupModel groupModel = (GroupModel) getGroup(groupPosition); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) (Context.LAYOUT_INFLATER_SERVICE); convertView = (.group_item, null); } ImageView groupIcon = (.group_icon); TextView groupTextView = (.group_name); (()); return convertView; } @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildModel childModel = (ChildModel) getChild(groupPosition, childPosition); if (convertView == null) { LayoutInflater inflater = (LayoutInflater) (Context.LAYOUT_INFLATER_SERVICE); convertView = (.child_item, null); } ImageView childIcon = (.child_icon); TextView childTextView = (.child_name); (()); return convertView; }
Through custom views, we can add more controls, such as pictures, buttons, etc. to grouping and child items, thereby achieving more complex interface effects.
8. Summary
ExpandableListView is a very practical list control in Android. It can help us implement list display with grouping functions. Through the introduction of this article, you should have mastered the basic usage of ExpandableListView, including the addition of layout files, the creation of data models, the implementation of adapters, the processing of click events, and the application of custom views. In actual development, you can further expand and optimize it according to specific needs to meet different business scenarios. I hope this article will be helpful to you and wish you better results in Android development!