The magic is quite simple, it mainly consists in storing the type of selection in the ActionMode.Callback's onItemCheckedStateChanged() method:
@Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { int count = lv.getCheckedItemCount(); if (count == 1) { expandableListSelectionType = ExpandableListView.getPackedPositionType( lv.getExpandableListPosition(position)); } mode.setTitle(String.valueOf(count)); configureMenu(mode.getMenu(), count); }
Then you need to implement onChildClick() and onGroupClick() listeners that check the list items once action mode is active:
@Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { if (mActionMode != null) { if (expandableListSelectionType == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { int flatPosition = parent.getFlatListPosition(ExpandableListView.getPackedPositionForGroup(groupPosition)); parent.setItemChecked( flatPosition, !parent.isItemChecked(flatPosition)); return true; } } return false; } @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { if (mActionMode != null) { if (expandableListSelectionType == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { int flatPosition = parent.getFlatListPosition( ExpandableListView.getPackedPositionForChild(groupPosition,childPosition)); parent.setItemChecked( flatPosition, !parent.isItemChecked(flatPosition)); } return true; } return false; }
The sample project also illustrates a technique of defining the context actions as part of four groups, depending on two combined criteria:
- actions for groups or children
- bulk actions that can be applied to multiple items, and single item actions