第一步创建布局
主布局
<ExpandableListView android:id="@+id/expend_list" android:layout_width="match_parent" android:layout_height="match_parent"></ExpandableListView>
父item布局
<TextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/label_group_normal" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="@android:color/holo_blue_light" android:gravity="center_vertical" android:paddingBottom="8dp" android:paddingLeft="32dp" android:paddingTop="8dp" android:textColor="@android:color/white" android:textSize="20sp" tools:text="测试数据"/>
子item布局
<TextView xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/expand_child" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="center" android:textSize="16sp" android:paddingTop="8dp" android:paddingBottom="8dp" tools:text="测试数据"/>
第二步适配器
public class MyExtendableListViewAdapter extends BaseExpandableListAdapter { @Override // 获取分组的个数 public int getGroupCount() { return groupString.length; } //获取指定分组中的子选项的个数 @Override public int getChildrenCount(int groupPosition) { return childString[groupPosition].length; } // 获取指定的分组数据 @Override public Object getGroup(int groupPosition) { return groupString[groupPosition]; } //获取指定分组中的指定子选项数据 @Override public Object getChild(int groupPosition, int childPosition) { return childString[groupPosition][childPosition]; } //获取指定分组的ID, 这个ID必须是唯一的 @Override public long getGroupId(int groupPosition) { return groupPosition; } //获取子选项的ID, 这个ID必须是唯一的 @Override public long getChildId(int groupPosition, int childPosition) { return childPosition; } //分组和子选项是否持有稳定的ID, 就是说底层数据的改变会不会影响到它们 @Override public boolean hasStableIds() { return true; } /** * * 获取显示指定组的视图对象 * * @param groupPosition 组位置 * @param isExpanded 该组是展开状态还是伸缩状态 * @param convertView 重用已有的视图对象 * @param parent 返回的视图对象始终依附于的视图组 */ // 获取显示指定分组的视图 @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { GroupViewHolder groupViewHolder; if (convertView == null){ convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.partent_item,parent,false); groupViewHolder = new GroupViewHolder(); groupViewHolder.tvTitle = (TextView)convertView.findViewById(R.id.label_group_normal); convertView.setTag(groupViewHolder); }else { groupViewHolder = (GroupViewHolder)convertView.getTag(); } groupViewHolder.tvTitle.setText(groupString[groupPosition]); return convertView; } /** * * 获取一个视图对象,显示指定组中的指定子元素数据。 * * @param groupPosition 组位置 * @param childPosition 子元素位置 * @param isLastChild 子元素是否处于组中的最后一个 * @param convertView 重用已有的视图(View)对象 * @param parent 返回的视图(View)对象始终依附于的视图组 * @return * @see android.widget.ExpandableListAdapter#getChildView(int, int, boolean, android.view.View, * android.view.ViewGroup) */ //取得显示给定分组给定子位置的数据用的视图 @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { ChildViewHolder childViewHolder; if (convertView==null){ convertView = LayoutInflater.from(parent.getContext()).inflate(R.layout.child_item,parent,false); childViewHolder = new ChildViewHolder(); childViewHolder.tvTitle = (TextView)convertView.findViewById(R.id.expand_child); convertView.setTag(childViewHolder); }else { childViewHolder = (ChildViewHolder) convertView.getTag(); } childViewHolder.tvTitle.setText(childString[groupPosition][childPosition]); return convertView; } //指定位置上的子元素是否可选中 @Override public boolean isChildSelectable(int groupPosition, int childPosition) { return true; } class GroupViewHolder { TextView tvTitle; } class ChildViewHolder { TextView tvTitle; } }
第三步使用及设置数据源
public String[] groupString = {"射手", "辅助", "坦克", "法师"}; public String[][] childString = { {"孙尚香", "后羿", "马可波罗", "狄仁杰"}, {"孙膑", "蔡文姬", "鬼谷子", "杨玉环"}, {"张飞", "廉颇", "牛魔", "项羽"}, {"诸葛亮", "王昭君", "安琪拉", "干将"} };
expandableListView=findViewById(R.id.expend_list); expandableListView.setAdapter(new MyExtendableListViewAdapter()); //设置分组的监听 expandableListView.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { Toast.makeText(getApplicationContext(), groupString[groupPosition], Toast.LENGTH_SHORT).show(); return false; } }); expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { int count = new MyExtendableListViewAdapter().getGroupCount(); for(int i = 0;i < count;i++){ if (i!=groupPosition){ expandableListView.collapseGroup(i); } } } }); //设置子项布局监听 expandableListView.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Toast.makeText(getApplicationContext(), childString[groupPosition][childPosition], Toast.LENGTH_SHORT).show(); return true; } });
其中设置单个展开代码为:
expandableListView.setOnGroupExpandListener(new ExpandableListView.OnGroupExpandListener() { @Override public void onGroupExpand(int groupPosition) { int count = new MyExtendableListViewAdapter().getGroupCount(); for(int i = 0;i < count;i++){ if (i!=groupPosition){ expandableListView.collapseGroup(i); } } } });
设置箭头在右边在主布局和父item布局中加入
android:layoutDirection="rtl"