ExpandableListView控件的使用

目录

一、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 ID
    final int CONTEXT_MENU_GROUP_RENAME = 1;
    final int CONTEXT_MENU_CHILD_EDIT = 2;
    final int CONTEXT_MENU_CHILD_DELETE = 3;
    @Override
    protected 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() {
            @Override
            public 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;
            }
        });
    }
    /*
     * 添加上下文菜单
     */
    @Override
    public 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, "删除");
        }

    }
    /*
     * 每个菜单项的具体点击事件
     */
    @Override
    public 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的list
    private 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;
    }


    /**
     * 取得分组数
     */
    @Override
    public int getGroupCount() {
        return groupTitle.size();
    }
    /**
     * 取得指定分组的子元素数
     */
    @Override
    public int getChildrenCount(int groupPosition) {
        return childMap.get(groupPosition).size();
    }

    /**
     * 获取指定组的数据对象。
     * @param groupPosition
     * @return
     */
    @Override
    public Object getGroup(int groupPosition) {
        return groupTitle.get(groupPosition);
    }

    /**
     * 获取指定子项的数据对象。
     * @param groupPosition 每组的id
     * @param childPosition 子项的id
     * @return
     */
    @Override
    public Object getChild(int groupPosition, int childPosition) {
        //我们这里返回一下每个item的名称,以便单击item时显示
        return childMap.get(groupPosition).get(childPosition).getTitle();
    }

    /**
     * 得指定分组的ID
     * @param groupPosition 组的ID
     * @return groupPosition
     */
    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

    @Override
    public long getChildId(int groupPosition, int childPosition) {
        return childPosition;
    }

    /**
     * 判断分组和子项的ID是否稳定。
     * @return
     */
    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public 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;
    }

    @Override
    public 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
     */
    @Override
    public 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"?>
<LinearLayout
    android:layout_height="match_parent"
    android:layout_width="match_parent"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <ExpandableListView
        android: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">
    <ImageView
        android:layout_marginTop="10dp"
        android:layout_height="50dp"
        android:layout_width="50dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="20dp"
        android:id="@+id/img_child"/>

    <TextView
        android: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">
    <ImageView
        android:layout_marginTop="10dp"
        android:layout_height="50dp"
        android:layout_width="50dp"
        android:layout_centerVertical="true"
        android:layout_marginLeft="10dp"
        android:id="@+id/img_group"/>

    <TextView
        android: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博客


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值