¿Cómo se puede implementar la selección múltiple y el Modo de acción contextual en ActionBarSherlock?

¿Cómo debería implementar la selección múltiple en AdapterView con ActionBarSherlock porque no proporciona MultiChoiceModeListener?

Esto es lo que parece

Modo de acción contextual

¿Cómo puedes hacer esto?

Entonces esto es lo que hice.

Editar: Ha pasado más de un año desde que descubrí que la respuesta anterior tenía un montón de código inútil (woops) y lo de CAB se puede lograr con mucho menos esfuerzo y un código más limpio, así que me tomé un tiempo y lo actualicé

LibraryFragment ListView se debe definir con el modo de selección “none”

 

El elemento de la lista debe tener un primer plano? Attr / activatedBackgroundIndicator para dibujar automáticamente la superposición semitransparente resaltada en list.setItemChecked (pos, true)

list_item_library.xml

  .... 

The ListFragment

 import android.support.v4.app.DialogFragment; import com.actionbarsherlock.app.SherlockListFragment; import com.actionbarsherlock.view.ActionMode; import com.actionbarsherlock.view.Menu; public final class LibraryFragment extends SherlockListFragment { private MyListAdapter adapter; private ListView list; // if ActoinMode is null - assume we are in normal mode private ActionMode actionMode; @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_library, null); this.list = (ListView) v.findViewById(android.R.id.list); this.initListView(); return v; } @Override public void onPause() { super.onPause(); if (this.actionMode != null) { this.actionMode.finish(); } } @Override public void onResume() { super.onResume(); updateData(); } // update ListView protected void updateData() { if (adapter == null) { return; } adapter.clear(); // my kinda stuff :) File[] items = scan(); if (items != null) { adapter.updateData(items); if (actionMode != null) { actionMode.invalidate(); } } // if empty - finish action mode. if (actionMode != null && (files == null || files.length == 0)) { actionMode.finish(); } } private void initListView() { this.adapter = new MyAdapter(getActivity()); this.list.setAdapter(adapter); this.list.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView arg0, View arg1, int arg2, long arg3) { if (actionMode != null) { // if already in action mode - do nothing return false; } // set checked selected item and enter multi selection mode list.setChoiceMode(AbsListView.CHOICE_MODE_MULTIPLE); list.setItemChecked(arg2, true); getSherlockActivity().startActionMode( new ActionModeCallback()); return true; } }); this.list.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView arg0, View arg1, int arg2, long arg3) { if (actionMode != null) { // the items are auomatically "checked" becaise we've set AbsListView.CHOICE_MODE_MULTIPLE before // starting action mode, so the only thing we have to care about is invalidating the actionmode actionMode.invalidate(); //invalidate title and menus. } else { // do whatever you should on item click } } }); } // all our ActionMode stuff here :) private final class ActionModeCallback implements ActionMode.Callback { // " selected" string resource to update ActionBar text private String selected = getActivity().getString( R.string.library_selected); @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { actionMode = mode; return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // remove previous items menu.clear(); final int checked = list.getCheckedItemCount(); // update title with number of checked items mode.setTitle(checked + this.selected); switch (checked) { case 0: // if nothing checked - exit action mode mode.finish(); return true; case 1: // all items - rename + delete getSherlockActivity().getSupportMenuInflater().inflate( R.menu.library_context, menu); return true; default: getSherlockActivity().getSupportMenuInflater().inflate( R.menu.library_context, menu); // remove rename option - because we have more than one selected menu.removeItem(R.id.library_context_rename); return true; } } @Override public boolean onActionItemClicked(ActionMode mode, com.actionbarsherlock.view.MenuItem item) { SparseBooleanArray checked; switch (item.getItemId()) { case R.id.library_context_rename: // the rename action is present only when only one item is selected. // so when the first checked item found, show the dialog and break checked = list.getCheckedItemPositions(); for (int i = 0; i < checked.size(); i++) { final int index = checked.keyAt(i); if (checked.get(index)) { final DialogFragment d = RenameDialog.instantiate(adapter.getItem(index).getFile(), LibraryFragment.this); d.show(getActivity().getSupportFragmentManager(), "dialog"); break; } } return true; case R.id.library_context_delete: // delete every checked item checked = list.getCheckedItemPositions(); for (int i = 0; i < checked.size(); i++) { final int index = checked.keyAt(i); if (checked.get(index)) { adapter.getItem(index).getFile().delete(); } } updateData(); return true; default: return false; } } @Override public void onDestroyActionMode(ActionMode mode) { list.clearChoices(); //workaround for some items not being unchecked. //see http://stackoverflow.com/a/10542628/1366471 for (int i = 0; i < list.getChildCount(); i++) { (list.getChildAt(i).getBackground()).setState(new int[] { 0 }); } list.setChoiceMode(AbsListView.CHOICE_MODE_NONE); actionMode = null; } } 

Hay una solución completa para esto …

https://github.com/deniskratinov/selectablelistview

Espero que esto te ayude…

su solución es la mejor y más fácil solución para este hilo. Pero hay un pequeño problema en el getView (): consulte de nuevo mis comentarios anteriores.

 int version = android.os.Build.VERSION.SDK_INT; if(version < 11){ if (checkedItems.contains(Integer.valueOf(position))) { convertView.getBackground().setState( new int[] { android.R.attr.state_checked }); } else { convertView.getBackground().setState( new int[] { -android.R.attr.state_checked }); } }else{ if (checkedItems.contains(Integer.valueOf(position))) { convertView.setActivated(true); } else { convertView.setActivated(false); } } 

Esto le dará soporte completo de API8 a API18