目录
一、ExpandableListView的介绍
二、适配器(ExpandableAdapter)
1、BaseExpandableListAdapter:
BaseExpandableListAdapter例子
一、ExpandableListView的介绍
ExpandableListView是ListView的子类。它是ListView的基础上进行了扩展,把应用中的列表分成几组,每组里又可以包含多个列表项。
二、适配器(ExpandableAdapter)
1、BaseExpandableListAdapter:
BaseExpandableListAdapter是一个抽象类,用于实现可扩展的列表视图(ExpandableListView)。它包含了一些方法来帮助你管理和填充可扩展列表视图中的数据。以下是BaseExpandableListAdapter中常用的方法及其功能:
| 方法名 | 功能 | 
| public abstract int getGroupCount() | 获取分组数量,即可扩展列表视图中的组数。 | 
| public abstract int getChildrenCount(int groupPosition) | 获取指定组中子项的数量。 | 
| public abstract Object getGroup(int groupPosition) | 获取指定组的数据对象。 | 
| public abstract Object getChild(int groupPosition, int childPosition) | 获取指定子项的数据对象。 | 
| public abstract long getGroupId(int groupPosition) | 获取指定组的ID。 | 
| public abstract long getChildId(int groupPosition, int childPosition) | 获取指定子项的ID。 | 
| public abstract boolean hasStableIds() | 判断分组和子项的ID是否稳定。 | 
| public abstract View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) | 获取指定组的视图对象。 | 
| public abstract View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) | 获取指定子项的视图对象。 | 
| public abstract boolean isChildSelectable(int groupPosition, int childPosition) | 判断指定子项是否可以被选中。 | 
这些方法提供了访问和操作可扩展列表视图中数据的基本功能。通过继承BaseExpandableListAdapter并重写这些方法,可以实现自定义的可扩展列表视图适配器,以满足各种实际应用的需求。
BaseExpandableListAdapter例子:
MainActivity:
package com.example.expandablelistdemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;
import android.view.ContextMenu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ExpandableListView;
import android.widget.Toast;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class MainActivity extends AppCompatActivity {private ExpandableListView expandList;private List<String> groupData;//group的数据源private Map<Integer, List<ChildItem>> childData;//child的数据源private MyAdapter myAdapter;final int CONTEXT_MENU_GROUP_DELETE = 0;//添加上下文菜单时每一个菜单项的item IDfinal int CONTEXT_MENU_GROUP_RENAME = 1;final int CONTEXT_MENU_CHILD_EDIT = 2;final int CONTEXT_MENU_CHILD_DELETE = 3;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);initData();initView();}private void initData() {groupData = new ArrayList<>();groupData.add("第一组");groupData.add("第二组");groupData.add("第三组");List<ChildItem> childItems = new ArrayList<>();for (int i = 0; i < 10; i++) {ChildItem childData = new ChildItem("标题:"+i, R.drawable.ic_launcher_background);childItems.add(childData);}List<ChildItem> childItems2 = new ArrayList<ChildItem>();for (int i = 0; i < 5; i++) {ChildItem childData1 = new ChildItem("标题:"+i, R.drawable.ic_launcher_background);childItems2.add(childData1);}List<ChildItem> childItems3 = new ArrayList<ChildItem>();for (int i = 0; i < 2; i++) {ChildItem childData1 = new ChildItem("标题:"+i, R.drawable.ic_launcher_background);childItems3.add(childData1);}childData = new HashMap<Integer, List<ChildItem>>();childData.put(0, childItems);childData.put(1, childItems2);childData.put(2, childItems3);myAdapter = new MyAdapter(this, groupData, childData);}private void initView() {expandList = findViewById(R.id.expandlist);expandList.setAdapter(myAdapter);// 添加上下文的菜单registerForContextMenu(expandList);// 给子项添加点击事件expandList.setOnChildClickListener(new ExpandableListView.OnChildClickListener() {@Overridepublic boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) {Toast.makeText(MainActivity.this, "你单击了:"+myAdapter.getChild(groupPosition, childPosition), Toast.LENGTH_SHORT).show();return true;}});}/** 添加上下文菜单*/@Overridepublic void onCreateContextMenu(ContextMenu menu, View v,ContextMenu.ContextMenuInfo menuInfo) {super.onCreateContextMenu(menu, v, menuInfo);ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo)menuInfo;int type = ExpandableListView.getPackedPositionType(info.packedPosition);if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {menu.setHeaderTitle("Options");menu.add(0, CONTEXT_MENU_GROUP_DELETE, 0, "删除");menu.add(0, CONTEXT_MENU_GROUP_RENAME, 0, "重命名");}if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) {menu.setHeaderTitle("Options");menu.add(1, CONTEXT_MENU_CHILD_EDIT, 0, "编辑");menu.add(1, CONTEXT_MENU_CHILD_DELETE, 0, "删除");}}/** 每个菜单项的具体点击事件*/@Overridepublic boolean onContextItemSelected(MenuItem item) {ExpandableListView.ExpandableListContextMenuInfo info = (ExpandableListView.ExpandableListContextMenuInfo)item.getMenuInfo();switch (item.getItemId()) {case CONTEXT_MENU_GROUP_DELETE:Toast.makeText(this, "这是group的删除", Toast.LENGTH_SHORT).show();break;case CONTEXT_MENU_GROUP_RENAME:Toast.makeText(this, "这是group的重命名", Toast.LENGTH_SHORT).show();break;case CONTEXT_MENU_CHILD_EDIT:Toast.makeText(this, "这是child的编辑", Toast.LENGTH_SHORT).show();break;case CONTEXT_MENU_CHILD_DELETE:Toast.makeText(this, "这是child的删除", Toast.LENGTH_SHORT).show();break;default:break;}return super.onContextItemSelected(item);}
} 
MyAdapter:
package com.example.expandablelistdemo;import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseExpandableListAdapter;
import android.widget.ImageView;
import android.widget.TextView;import java.util.List;
import java.util.Map;public class MyAdapter extends BaseExpandableListAdapter{private Context mContext;// 每组的标题private List<String> groupTitle;//子项是一个map,key是group的id,每一个group对应一个ChildItem的listprivate Map<Integer, List<ChildItem>> childMap;public MyAdapter(Context context, List<String> groupTitle, Map<Integer, List<ChildItem>> childMap){this.mContext = context;this.groupTitle = groupTitle;this.childMap = childMap;}/*** 取得分组数*/@Overridepublic int getGroupCount() {return groupTitle.size();}/*** 取得指定分组的子元素数*/@Overridepublic int getChildrenCount(int groupPosition) {return childMap.get(groupPosition).size();}/*** 获取指定组的数据对象。* @param groupPosition* @return*/@Overridepublic Object getGroup(int groupPosition) {return groupTitle.get(groupPosition);}/*** 获取指定子项的数据对象。* @param groupPosition 每组的id* @param childPosition 子项的id* @return*/@Overridepublic Object getChild(int groupPosition, int childPosition) {//我们这里返回一下每个item的名称,以便单击item时显示return childMap.get(groupPosition).get(childPosition).getTitle();}/*** 得指定分组的ID* @param groupPosition 组的ID* @return groupPosition*/@Overridepublic long getGroupId(int groupPosition) {return groupPosition;}@Overridepublic long getChildId(int groupPosition, int childPosition) {return childPosition;}/*** 判断分组和子项的ID是否稳定。* @return*/@Overridepublic boolean hasStableIds() {return true;}@Overridepublic View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {GroupHolder groupHolder = null;if (convertView == null){convertView = LayoutInflater.from(mContext).inflate(R.layout.group_item,null);groupHolder = new GroupHolder();groupHolder.groupImg = convertView.findViewById(R.id.img_group);groupHolder.groupTitle =  convertView.findViewById(R.id.tv_group_title);convertView.setTag(groupHolder);}else {groupHolder = (GroupHolder) convertView.getTag();}// 如果group被展开if (isExpanded){groupHolder.groupImg.setBackgroundResource(R.drawable.downarrow);}else {groupHolder.groupImg.setBackgroundResource(R.drawable.rightarrow);}groupHolder.groupTitle.setText(groupTitle.get(groupPosition));return convertView;}@Overridepublic View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {ChildHolder childHolder = null;if (convertView == null) {convertView = LayoutInflater.from(mContext).inflate(R.layout.child_item, null);childHolder = new ChildHolder();childHolder.childImg = convertView.findViewById(R.id.img_child);childHolder.childTitle =  convertView.findViewById(R.id.tv_child_text);convertView.setTag(childHolder);}else {childHolder = (ChildHolder) convertView.getTag();}childHolder.childImg.setBackgroundResource(childMap.get(groupPosition).get(childPosition).getMarkerImgId());childHolder.childTitle.setText(childMap.get(groupPosition).get(childPosition).getTitle());return convertView;}/*** 判断指定子项是否可以被选中。* @param groupPosition* @param childPosition* @return*/@Overridepublic boolean isChildSelectable(int groupPosition, int childPosition) {return true;}private class GroupHolder{ImageView groupImg;TextView groupTitle;}private class ChildHolder{ImageView childImg;TextView childTitle;}}
 
GroupItem:
package com.example.expandablelistdemo;public class GroupItem {private String title;private int imageId;private GroupItem(String title,int imageId){this.title = title;this.imageId = imageId;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public int getImageId() {return imageId;}public void setImageId(int imageId) {this.imageId = imageId;}
} 
ChildItem:
package com.example.expandablelistdemo;public class ChildItem {private String title;private int markerImgId;public ChildItem(String title,int markerImgId){this.markerImgId = markerImgId;this.title = title;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public int getMarkerImgId() {return markerImgId;}public void setMarkerImgId(int markerImgId) {this.markerImgId = markerImgId;}
} 
activity_main:
<?xml version="1.0" encoding="UTF-8"?>
<LinearLayoutandroid:layout_height="match_parent"android:layout_width="match_parent"xmlns:android="http://schemas.android.com/apk/res/android"><ExpandableListViewandroid:layout_height="match_parent"android:layout_width="match_parent"android:dividerHeight="1dp"android:divider="@android:color/white"android:cacheColorHint="#00000000"android:id="@+id/expandlist"/></LinearLayout> 
child_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="horizontal"android:layout_height="match_parent"><ImageViewandroid:layout_marginTop="10dp"android:layout_height="50dp"android:layout_width="50dp"android:layout_centerVertical="true"android:layout_marginLeft="20dp"android:id="@+id/img_child"/><TextViewandroid:layout_marginTop="21dp"android:id="@+id/tv_child_text"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="20dp"android:layout_toRightOf="@id/img_child"android:text="xiangjiao"android:textSize="16sp" />
</LinearLayout> 
group_item:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:orientation="horizontal"android:layout_height="match_parent"><ImageViewandroid:layout_marginTop="10dp"android:layout_height="50dp"android:layout_width="50dp"android:layout_centerVertical="true"android:layout_marginLeft="10dp"android:id="@+id/img_group"/><TextViewandroid:layout_marginTop="21dp"android:id="@+id/tv_group_title"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_centerVertical="true"android:layout_marginLeft="20dp"android:layout_toRightOf="@id/img_child"android:text="水果"android:textSize="16sp" />
</LinearLayout> 
效果图:


上一篇:ListView的使用:ListView控件的使用_敬往事一杯酒哈的博客-CSDN博客
  














