Android中的二级下拉列表,类似于某Q的分组,采用ExpandableListView实现,适配器方法如下。
先看效果图:有四个分组,每个分组下都有一些子条目,可以跟着父条目展开而显示
一级列表是一个ArrayList,二级列表是一个HashMap。
//添加一级数据项 存储一级菜单的名字
ArrayList firstLevelMenuList = SeatModelManager.getInstance().getTxGroups();
//二级数据
LinkedHashMap> secondItems = new LinkedHashMap<>();
ArrayList txNameList;
for (int i = 0; i < firstLevelMenuList.size(); i++) {
ArrayList 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);
适配器,构造方法里的代码根据需要进行编写
public class ExpandableListviewAdapter extends BaseExpandableListAdapter {
private static final String TAG = "ExpandableListviewAdapt";
private ArrayList firstItems;
private Map> secondItems;
private Map secondItemSelection;//记录子条目选中状态
private List selectChildItems;//记录子条目的顺序
public ExpandableListviewAdapter(Context context, ArrayList firstItems, Map> 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 getSelectChildItems() {
ArrayList selectItems = new ArrayList<>();
for (String firstItem : firstItems) {
boolean[] selection = secondItemSelection.get(firstItem);
List second = secondItems.get(firstItem);
for (int i = 0; i < selection.length; i++) {
if (selection[i]) {
selectItems.add(second.get(i));
}
}
}
//创建新的列表 按照顺序添加子条目
ArrayList 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 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 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 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 childList) {
notifyDataSetChanged();
}
public void updateChildView() {
notifyDataSetChanged();
}
static class GroupViewHolder {
TextView parentTv;
}
}