2.5.5 Basic Usage of ExpandableListView (Collapsible List)
Category Android Basic Tutorial
Introduction to This Section:
>
This section will discuss the Adapter class control known as ExpandableListView, which is a collapsible list and a subclass of ListView. On the basis of ListView, it divides the list items in the application into several groups, and each group can contain multiple list items. In terms of appearance, it is similar to the QQ contact list. Its usage is very similar to ListView, except that the list items displayed by ExpandableListView need to be provided by ExpandableAdapter. Let's learn about the basic usage of this control!
Official API: ExpandableListView
1. Related Attributes
>
android:childDivider: Specifies the divider between child list items within each group. The image will not be fully displayed, and a straight line separates the child list items.
android:childIndicator: The Drawable object displayed next to the child list, which can be an image.
android:childIndicatorEnd: The end constraint position of the child list item indicator.
android:childIndicatorLeft: The left constraint position of the child list item indicator.
android:childIndicatorRight: The right constraint position of the child list item indicator.
android:childIndicatorStart: The start constraint position of the child list item indicator.
android:groupIndicator: The Drawable object displayed next to the group list, which can be an image.
android:indicatorEnd: The end constraint position of the group list item indicator.
android:indicatorLeft: The left constraint position of the group list item indicator.
android:indicatorRight: The right constraint position of the group list item indicator.
android:indicatorStart: The start constraint position of the group list item indicator.
2. Three Ways to Implement ExpandableAdapter
>
1. Extend BaseExpandableListAdapter to implement ExpandableAdapter.
2. Use SimpleExpandableListAdapter to wrap two List collections into ExpandableAdapter.
3. Use simpleCursorTreeAdapter to wrap the data in the Cursor into a SimpleCursorTreeAdapter.
This section's example uses the first method, extending BaseExpandableListAdapter. We need to override the relevant methods of this class. Let's experience it through a code example!
3. Code Example
Let's take a look at the effect diagram:
Now let's implement the effect shown in the above figure:
The core is to override BaseExpandableListAdapter, which is similar to the ordinary BaseAdapter we wrote before, but BaseExpandableListAdapter is divided into two parts: groups and child lists. You will understand by looking at the code!
Additionally, it is important to note that the method isChildSelectable() must return true, otherwise, the click event of the child Item will not be triggered! Let's write it:
First, the layouts for the group and child list:
itemexlistgroup.xml:
<?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="match_parent"
android:orientation="horizontal"
android:padding="5dp">
<TextView
android:id="@+id/tv_group_name"
android:layout_width="match_parent"
android:layout_height="56dp"
android:gravity="center_vertical"
android:paddingLeft="30dp"
android:text="AP"
android:textStyle="bold"
android:textSize="20sp" />
</LinearLayout>
itemexlistitem.xml:
<?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="match_parent"
android:orientation="horizontal"
android:padding="5dp"
android:background="#6BBA79">
<ImageView
android:id="@+id/img_icon"
android:layout_width="48dp"
android:layout_height="48dp"
android:src="@mipmap/iv_lol_icon1"
android:focusable="false"/>
<TextView
android:id="@+id/tv_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="15dp"
android:layout_marginTop="15dp
public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {
ViewHolderItem itemHolder;
if(convertView == null){
convertView = LayoutInflater.from(mContext).inflate(
R.layout.item_exlist_item, parent, false);
itemHolder = new ViewHolderItem();
itemHolder.img_icon = (ImageView) convertView.findViewById(R.id.img_icon);
itemHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
convertView.setTag(itemHolder);
}else{
itemHolder = (ViewHolderItem) convertView.getTag();
}
itemHolder.img_icon.setImageResource(iData.get(groupPosition).get(childPosition).getiId());
itemHolder.tv_name.setText(iData.get(groupPosition).get(childPosition).getiName());
return convertView;
}
//Set whether the child list can be selected
@Override
public boolean isChildSelectable(int groupPosition, int childPosition) {
return true;
}
private static class ViewHolderGroup{
private TextView tv_group_name;
}
private static class ViewHolderItem{
private ImageView img_icon;
private TextView tv_name;
}
}
PS: The data for the child list does not necessarily have to use ArrayList<ArrayList
The last part is the layout and Java code for MainActivity:
Layout file: **activity_main.xml**:
<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:padding="5dp" tools:context=".MainActivity">
<ExpandableListView
android:id="@+id/exlist_lol"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:childDivider="#E02D2F"/>
</RelativeLayout>
**MainActivity.java**:
public class MainActivity extends AppCompatActivity {
private ArrayList<Group> gData = null;
private ArrayList<ArrayList<Item>> iData = null;
private ArrayList<Item> lData = null;
private Context mContext;
private ExpandableListView exlist_lol;
private MyBaseExpandableListAdapter myAdapter = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
exlist_lol = (ExpandableListView) findViewById(R.id.exlist_lol);
//Data preparation
gData = new ArrayList<Group>();
iData = new ArrayList<ArrayList<Item>>();
gData.add(new Group("AD"));
gData.add(new Group("AP"));
gData.add(new Group("TANK"));
lData = new ArrayList<Item>();
//AD group
lData.add(new Item(R.mipmap.iv_lol_icon3,"Yasuo"));
lData.add(new Item(R.mipmap.iv_lol_icon4,"Draven"));
lData.add(new Item(R.mipmap.iv_lol_icon13,"Graves"));
lData.add(new Item(R.mipmap.iv_lol_icon14,"Vayne"));
iData.add(lData);
//AP group
lData = new ArrayList<Item>();
lData.add(new Item(R.mipmap.iv_lol_icon1, "Teemo"));
lData.add(new Item(R.mipmap.iv_lol_icon7, "Annie"));
lData.add(new Item(R.mipmap.iv_lol_icon8, "Kayle"));
lData.add(new Item(R.mipmap.iv_lol_icon9, "Zed"));
lData.add(new Item(R.mipmap.iv_lol_icon11, "Ahri"));
iData.add(lData);
//TANK group
lData = new ArrayList<Item>();
lData.add(new Item(R.mipmap.iv_lol_icon2, "Darius"));
lData.add(new Item(R.mipmap.iv_lol_icon5, "Xin Zhao"));
lData.add(new Item(R.mipmap.iv_lol_icon6, "Olaf"));
lData.add(new Item(R.mipmap.iv_lol_icon10, "Shyvana"));
lData.add(new Item(R.mipmap.iv_lol_icon12, "Ursho"));
iData.add(lData);
myAdapter = new MyBaseExpandableListAdapter(gData,iData,mContext);
exlist_lol.setAdapter(myAdapter);
//Set click event for the list
exlist_lol.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {
@Override
public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {
Toast.makeText(mContext, "You clicked: " + iData.get(groupPosition).get(childPosition).getiName(), Toast.LENGTH_SHORT).show();
1.8 Project-Related Analysis (Various Files, Resource Access)
2.5.4 Basic Usage of AutoCompleteTextView (Auto-complete Text Box)
2.5.5 Basic Usage of ExpandableListView (Expandable List)
2.5.8 Detailed Explanation of Notification (Status Bar Notification)
[2.6.4 Simple Usage of DrawerLayout (Official Side-slip Menu)]
8.3.4 Paint API - Xfermode and PorterDuff Detailed Explanation (I)
8.3.5 Paint API - Xfermode and PorterDuff Detailed Explanation (II)
8.3.6 Paint API - Xfermode and PorterDuff Detailed Explanation (III)
8.3.7 Paint API - Xfermode and PorterDuff Detailed Explanation (IV)
8.3.8 Paint API - Xfermode and PorterDuff Detailed Explanation (V)
8.3.14 Paint Several Enumeration/Constant Values and ShadowLayer Shadow Effects
8.3.17 Detailed Explanation of Canvas API (Part 2) - Collection of Clipping Methods
[8.3.18 Detailed