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

}
相关推荐
鲤籽鲲4 分钟前
C# Random 随机数 全面解析
android·java·c#
m0_548514774 小时前
2024.12.10——攻防世界Web_php_include
android·前端·php
凤邪摩羯4 小时前
Android-性能优化-03-启动优化-启动耗时
android
凤邪摩羯4 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析
android
喀什酱豆腐5 小时前
Handle
android
m0_748232926 小时前
Android Https和WebView
android·网络协议·https
m0_748251727 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)
android·游戏·unity
m0_748254668 小时前
go官方日志库带色彩格式化
android·开发语言·golang
zhangphil8 小时前
Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)
android·kotlin
爱学测试的李木子9 小时前
从0到1搭建 Android 自动化 python+appium 环境
android·软件测试·python·测试工具·自动化