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;
    }

}
相关推荐
Estar.Lee13 分钟前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
找藉口是失败者的习惯1 小时前
从传统到未来:Android XML布局 与 Jetpack Compose的全面对比
android·xml
Jinkey2 小时前
FlutterBasic - GetBuilder、Obx、GetX<Controller>、GetxController 有啥区别
android·flutter·ios
大白要努力!4 小时前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟5 小时前
Android音频采集
android·音视频
小白也想学C6 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程6 小时前
初级数据结构——树
android·java·数据结构
闲暇部落8 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX10 小时前
Android 分区相关介绍
android
大白要努力!11 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle