Android中的二级列表-ExpandableListView

Android中的二级下拉列表,类似于某Q的分组,采用ExpandableListView实现,适配器方法如下。

先看效果图:有四个分组,每个分组下都有一些子条目,可以跟着父条目展开而显示

实现代码:

一级列表是一个ArrayList,二级列表是一个HashMap。

XML 复制代码
    <ExpandableListView
        android:id="@+id/expandableListView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:nestedScrollingEnabled="false"
        android:layout_weight="1"/>
java 复制代码
     //添加一级数据项 存储一级菜单的名字
        ArrayList<String> firstLevelMenuList = SeatModelManager.getInstance().getTxGroups();

        //二级数据
        LinkedHashMap<String, List<String>> secondItems = new LinkedHashMap<>();
        ArrayList<String> txNameList;

        for (int i = 0; i < firstLevelMenuList.size(); i++) {
            ArrayList<Tx> txes = SeatModelManager.getInstance().readTxByGroup(firstLevelMenuList.get(i));
            txNameList = new ArrayList<>();
            for (int j = 0; j < txes.size(); j++) {
               //根据一级菜单的名字匹配自己所在的父条目
                if (txes.get(j).getGroup().equals(firstLevelMenuList.get(i))) {
                    txNameList.add(txes.get(j).getTxName());
                }
            }
            secondItems.put(firstLevelMenuList.get(i), txNameList);
        }

        expandableListView = inflate.findViewById(R.id.expandableListView);
        expandableListAdapter = new ExpandableListviewAdapter(getActivity(), firstLevelMenuList, secondItems);
        expandableListView.setAdapter(expandableListAdapter);

适配器,构造方法里的代码根据需要进行编写

java 复制代码
public class ExpandableListviewAdapter extends BaseExpandableListAdapter {
    private static final String TAG = "ExpandableListviewAdapt";

    private ArrayList<String> firstItems;
    private Map<String, List<String>> secondItems;
    private Map<String, boolean[]> secondItemSelection;//记录子条目选中状态

    private List<String> selectChildItems;//记录子条目的顺序

    public ExpandableListviewAdapter(Context context, ArrayList<String> firstItems, Map<String, List<String>> secondItems) {
        this.context = context;
        this.firstItems = firstItems;
        this.secondItems = secondItems;
        secondItemSelection = new HashMap<>();
        selectChildItems = new ArrayList<>();//初始化子条目中的顺序列表
        //初始化子条目的选中状态
        for (String first : firstItems) {
            int secondCunt = secondItems.get(first).size();
            boolean[] selection = new boolean[secondCunt];
            secondItemSelection.put(first, selection);
        }
    }

    //返回当前被选中的子条目的数据
    public ArrayList<String> getSelectChildItems() {
        ArrayList<String> selectItems = new ArrayList<>();
        for (String firstItem : firstItems) {
            boolean[] selection = secondItemSelection.get(firstItem);
            List<String> second = secondItems.get(firstItem);
            for (int i = 0; i < selection.length; i++) {
                if (selection[i]) {
                    selectItems.add(second.get(i));
                }
            }
        }
        //创建新的列表 按照顺序添加子条目
        ArrayList<String> selectItemsInOrder = new ArrayList<>();
        for (String item : selectChildItems) {
            if (selectItems.contains(item)) {
                selectItemsInOrder.add(item);
            }
        }
        return selectItemsInOrder;
    }


    @Override
    public int getGroupCount() {
        return firstItems.size();
    }

    @Override
    public int getChildrenCount(int groupPosition) {
        String s = firstItems.get(groupPosition);
        List<String> strings = secondItems.get(s);
        return strings != null ? strings.size() : 0;
    }

    @Override
    public Object getGroup(int groupPosition) {
        return firstItems.get(groupPosition);
    }

    @Override
    public Object getChild(int groupPosition, int childPosition) {
        return secondItems.get(groupPosition);
    }

    @Override
    public long getGroupId(int groupPosition) {
        return groupPosition;
    }

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

    @Override
    public boolean hasStableIds() {
        return true;
    }

    @Override
    public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
        GroupViewHolder groupViewHolder;
        if (convertView == null) {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            convertView = inflater.inflate(R.layout.item_parent, null);
            groupViewHolder = new GroupViewHolder();
            groupViewHolder.parentTv = convertView.findViewById(R.id.item_parent_tv);
            groupViewHolder.parentTv.setText(firstItems.get(groupPosition));
            convertView.setTag(groupViewHolder);
        }
        return convertView;
    }

    TextView childNum;

    @Override
    public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) {

        if (convertView == null) {
            LayoutInflater inflater = LayoutInflater.from(parent.getContext());
            convertView = inflater.inflate(R.layout.item_child, parent, false);
        }

        //设置子布局
        String firstItem = firstItems.get(groupPosition);
        boolean[] selection = secondItemSelection.get(firstItem);
        boolean isSelect = selection[childPosition];
        String secondItem = secondItems.get(firstItem).get(childPosition);

        TextView childText = convertView.findViewById(R.id.item_child_tv);
        CheckBox childCb = convertView.findViewById(R.id.item_child_cb);
        childNum = convertView.findViewById(R.id.item_num);

        childText.setText(secondItem);
        childCb.setChecked(isSelect);

        //获取当前子条目在列表中的位置
        int index = getChildIndex(groupPosition, childPosition);
        if (index > 0) {
            childNum.setText(String.valueOf(index));//设置数字角标
            childNum.setVisibility(View.VISIBLE);
            childCb.setChecked(true);
        } else {
            childNum.setVisibility(View.INVISIBLE);
            childCb.setChecked(false);
        }


        //复选框的监听事件
        childCb.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isChecked = childCb.isChecked();
                selection[childPosition] = isChecked;
                //处理选中的状态逻辑
                if (isChecked) {
                    String childItem = secondItems.get(firstItem).get(childPosition);
                    selectChildItems.add(childItem);

                } else {
                    //子条目取消选中 移除选中的子条目
                    String childItem = secondItems.get(firstItem).get(childPosition);
                    selectChildItems.remove(childItem);
                }
                notifyDataSetChanged();
                List<String> selectChildItems = getSelectChildItems();
                Log.d(TAG, "getGroupView: " + selectChildItems);
            }
        });


        return convertView;
    }

    /**
     * 获取子条目在列表中的位置
     *
     * @param groupPosition
     * @param childPosition
     * @return
     */
    private int getChildIndex(int groupPosition, int childPosition) {
        String firstItem = firstItems.get(groupPosition);
        String secondItem = secondItems.get(firstItem).get(childPosition);
        int index = selectChildItems.indexOf(secondItem);
        // 由于索引从0开始,所以需要加1
        return index + 1;
    }


    public void setSelectChildItems(ArrayList<String> selectChildItems) {
        this.selectChildItems = selectChildItems;
//        for (int i = 0; i < selectChildItems.size(); i++) {
//            String s = selectChildItems.get(i);
//            for (String second : selectChildItems)
//                if (s.equals(second)) {
//
//                }
//        }
        notifyDataSetChanged();//更新页面显示
    }

    //指定位置上的子元素是否可选中
    @Override
    public boolean isChildSelectable(int groupPosition, int childPosition) {
        return true;
    }

    //刷新子条目数据
    public void updateChildData(int groupPosition, List<String> childList) {
        notifyDataSetChanged();
    }

    public void updateChildView() {
        notifyDataSetChanged();
    }

    static class GroupViewHolder {
        TextView parentTv;
    }

}
相关推荐
启雀AI10 小时前
培训平台移动端离线学习方案设计与实现:视频缓存、断点续传与进度同步的工程实践
android·学习·缓存·音视频·企业lms
我命由我1234511 小时前
RxJava - 冷数据流与热数据流
android·java·java-ee·android studio·rxjava·android-studio·android runtime
2601_9665635213 小时前
愤怒的小鸟单机版 去广告 安卓+PC端离线纯净版 益智耐玩小游戏 不需联网 老旧手机都可以玩 怀旧手机小游戏
android·智能手机
hunterandroid13 小时前
[Android 从零到一] Retrofit 请求取消与生命周期绑定:从 Call.cancel 到协程可取消设计
android
爱跑马的程序员13 小时前
安卓专有的通信子系统-Binder IPC
android·binder·ipc·安卓间通信机制
ue星空14 小时前
【安卓逆向】为什么用Frida?
android
小驰行动派15 小时前
Camx架构全景图:从V4L2到Pipeline的完整拆解
android·camera·android camera
hunterandroid15 小时前
[Android 从零到一] Custom View 触摸反馈与手势冲突解决
android
coderSong256816 小时前
Android | 四大组件之 BroadcastReceiver(广播接收器)
android
爱笑鱼19 小时前
Android 系统启动机制(二):init.rc 不是普通脚本,service、action 和 property 怎样驱动启动?
android