Stop ExpandableListView expands while the contextual action bar is displayed

I have a fragment containing an ExpandableListView . I would like to be able to select and delete items by groups. I would also like to be able to select multiple group members for deletion using the action context bar.

Until now, I could click on groups to view children, and I can click on children to go to another event. I set the selection mode of ExpandableListView to CHOICE_MODE_MULTIPLE_MODAL , and if I long-click in a group, it will be selected, a contextual action panel will appear. If I select my delete button, the item will be deleted. Things are good.

However, the problem occurs when I try to select multiple groups in CAB mode. It just doesn't work. If I press the second group, this group will be expanded (not selected). I want to be able to simply select several elements of a group without any extension.

There is a lot of code to work here, but I will try to show some relevant bits. The main problem is getting a list of selected group members. Secondly, I do not want the groups to expand as they are selected (while the CAB is visible - this is what I am trying while holding the ActionMode to mActionMode ).

Any help is greatly appreciated.

 ex.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { @Override public void onItemCheckedStateChanged(ActionMode actionMode, int position, long id, boolean checked) { // Ignore long clicks on children long pos = ex.getExpandableListPosition(position); if (checked && (ExpandableListView.getPackedPositionType(pos) == ExpandableListView.PACKED_POSITION_TYPE_CHILD)) { ex.setItemChecked(position, false); return; } } @Override public boolean onCreateActionMode(ActionMode actionMode, Menu menu) { MenuInflater inflater = actionMode.getMenuInflater(); inflater.inflate(R.menu.context_delete_items, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode actionMode, Menu menu) { mActionMode = actionMode; return false; } @Override public boolean onActionItemClicked(ActionMode actionMode, MenuItem item) { // If delete is clicked, delete the measurement set switch(item.getItemId()) { case(R.id.context_menu_delete_item): Set<mySet> setsToDelete = new HashSet<mySet>(); if (ex != null) { if (ex.getCheckedItemCount() > 0) { SparseBooleanArray checkedPositions = ex.getCheckedItemPositions(); for (int i = 0; i < checkedPositions.size(); i++) { int position = checkedPositions.keyAt(i); /* Ignore selected children */ long pos = ex.getExpandableListPosition(position); int groupPosition = ExpandableListView.getPackedPositionGroup(pos); if (checkedPositions.valueAt(i)) { Log.d(TAG, "Adding MeasurementSet at position Key = " + position + " to deletion list"); setsToDelete.add(mSets.get(groupPosition)); } } } } try { if (ex != null && setsToDelete.size() > 0) { ArrayList setsToDeleteList = new ArrayList(setsToDelete); deleteSets(setsToDeleteList); for (mySet s : setsToDelete) { mSets.remove(s); } Toast.makeText(getActivity(), "Set deleted successfully", Toast.LENGTH_LONG).show(); } } catch (SQLiteException sqlex) { Log.e(TAG, "Delete operation failed"); Log.e(TAG, "Error was: " + sqlex.getMessage()); Log.e(TAG, "Stack trace: " + sqlex.getStackTrace()); Toast.makeText(getActivity(), "There was an error whilst deleting Set(s): " + sqlex.getMessage(), Toast.LENGTH_LONG).show(); } actionMode.finish(); return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode actionMode) { mActionMode = null; } }); ex.setOnChildClickListener(new ExpandableListView.OnChildClickListener() { @Override public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, int childPosition, long id) { Long mId = mSets.get(groupPosition).getMyList().get(childPosition).getId(); Intent intent = new Intent(getActivity(), ViewSingleActivity.class); intent.putExtra(getResources().getString(R.string.EXTRA_MID_KEY), measurementId); startActivityForResult(intent, Constants.REQ_VIEW_M); return true; } }); // Here I was trying to intercept group clicks and force the clicked group to collapse. Although this doesn't seem to solve the issue of having the group "selected" ex.setOnGroupClickListener(new ExpandableListView.OnGroupClickListener() { @Override public boolean onGroupClick(ExpandableListView parent, View v, int groupPosition, long id) { if (mActionMode != null) { Log.d(TAG, "mActionMode is not null. Setting View: " + parent.toString() + " to be selected"); v.setSelected(true); Log.d(TAG, "Collapsing group " + groupPosition); parent.collapseGroup(groupPosition); } return false; } }); } 
+6
source share
1 answer

Although this is an old post, I thought that I would post an answer if anyone stumbles. The problem is that ExpandableListView does not support ChoiceMode. Although this seems to work, and you can manually manually call ExpandableListView to set items that have been checked ... it will never fully work correctly. For a deeper reason why; refer to these and this . Answer.

The OP did not indicate whether they wrote their own custom adapter or not. Therefore, I will consider both approaches.

If you want to write your own ExpandableListAdapter , I suggest using PatchedExpandabeListAdapter . You can read about it here . It basically fixes and improves some things ... one of which is the ChoiceMode issue posed by the OP.

If you don't want to roll back your own solution, there are two good full-fledged Rolodex adapters found here that implements the PatchedExpandabeListAdapter and much more that you need in addition to creating the view.

+1
source

All Articles