Множественный выбор в пользовательском ListView с CAB

После прочтения и попыток в течение нескольких дней я сдаюсь и прошу помощи.

Я использую ActionBarSherlock.

То, что я хочу достичь: ListView с пользовательским макетом для каждой строки, где пользователь может выбрать несколько элементов списка. Выбранный элемент списка должен иметь другой цвет фона. Когда есть хотя бы один выбранный элемент, должна отображаться панель контекстного действия (CAB). Он должен выглядеть более или менее похожим на множественный выбор писем в приложении GMail. Единственное различие заключается в том, что в приложении gmail выбор сделан, щелкнув флажок строки, тогда как я не хочу иметь флажок, но строка должна быть выбрана независимо от того, где пользователь нажимает. Множественный выбор в приложении GMail

То, что я пробовал: после этого урока , используя макет Checkable row с некоторой логикой для изменения цвета фона при переключении состояния проверки, я получил все, кроме того, что я не мог зарегистрировать прослушиватель кликов, такой как OnItemClickListener в ListView, чтобы показать CAB , Также не предоставлял прослушиватель кликов для каждой строки View, потому что это предотвратило изменение цвета фона для выбранных элементов. Я также попытался добавить MultiChoiceModeListener в ListView, как это

listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); listView.setMultiChoiceModeListener(new MultiChoiceModeListener() { //.. }); 

При том же результате цвет фона не меняется.

Что я ищу : подсказка или учебник или пример кода, как это сделать. Если вам нужны некоторые fragmentы кода, чтобы помочь, сообщите мне.

Посмотрите, помогает ли вам код (в основном это ListActivity с пользовательским адаптером для хранения статуса отмеченных элементов (+ другой фон)):

 public class CABSelection extends ListActivity { private ArrayList mItems = new ArrayList(); private SelectionAdapter mAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); for (int i = 0; i < 24; i++) { mItems.add("Name" + i); } // R.layout.adapters_cabselection_row is a LinearLayout(with green // background(#99cc00)) that wraps an ImageView and a TextView mAdapter = new SelectionAdapter(this, R.layout.adapters_cabselection_row, R.id.the_text, mItems); setListAdapter(mAdapter); getListView().setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); getListView().setMultiChoiceModeListener(new MultiChoiceModeListener() { private int nr = 0; @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.cabselection_menu, menu); return true; } @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { return false; } @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { StringBuilder sb = new StringBuilder(); Set positions = mAdapter.getCurrentCheckedPosition(); for (Integer pos : positions) { sb.append(" " + pos + ","); } switch (item.getItemId()) { case R.id.edit_entry: Toast.makeText(CABSelection.this, "Edited entries: " + sb.toString(), Toast.LENGTH_SHORT).show(); break; case R.id.delete_entry: Toast.makeText(CABSelection.this, "Deleted entries : " + sb.toString(), Toast.LENGTH_SHORT).show(); break; case R.id.finish_it: nr = 0; mAdapter.clearSelection(); Toast.makeText(CABSelection.this, "Finish the CAB!", Toast.LENGTH_SHORT).show(); mode.finish(); } return false; } @Override public void onDestroyActionMode(ActionMode mode) { nr = 0; mAdapter.clearSelection(); } @Override public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { if (checked) { nr++; mAdapter.setNewSelection(position, checked); } else { nr--; mAdapter.removeSelection(position); } mode.setTitle(nr + " rows selected!"); } }); } @Override protected void onListItemClick(ListView l, View v, int position, long id) { l.setItemChecked(position, !mAdapter.isPositionChecked(position)); } private class SelectionAdapter extends ArrayAdapter { private HashMap mSelection = new HashMap(); public SelectionAdapter(Context context, int resource, int textViewResourceId, List objects) { super(context, resource, textViewResourceId, objects); } public void setNewSelection(int position, boolean value) { mSelection.put(position, value); notifyDataSetChanged(); } public boolean isPositionChecked(int position) { Boolean result = mSelection.get(position); return result == null ? false : result; } public Set getCurrentCheckedPosition() { return mSelection.keySet(); } public void removeSelection(int position) { mSelection.remove(position); notifyDataSetChanged(); } public void clearSelection() { mSelection = new HashMap(); notifyDataSetChanged(); } @Override public View getView(int position, View convertView, ViewGroup parent) { View v = super.getView(position, convertView, parent);//let the adapter handle setting up the row views v.setBackgroundColor(Color.parseColor("#99cc00")); //default color if (mSelection.get(position) != null) { v.setBackgroundColor(Color.RED);// this is a selected position so make it red } return v; } } } 

R.layout.adapters_cabselection_row – это настраиваемый макет для строки (очень простой) с зеленым фоном:

      

R.menu.cabselection_menu – это файл меню с тремя параметрами (редактировать, удалять, заканчивать CAB), которые ничего не делают, кроме поп Toast с сообщением о выбранных строках:

       

Я думаю, что самый простой способ – применить

android:background="android:attr/activatedBackgroundIndicator"

К которой когда-либо был выбран макет, вы нажмете.

Это выделяет макет при выборе с помощью

 listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL); 

работал в любом случае

Использование ActionBarSherlock MultiChoiceModeListener используемое в ответе Luksprog, пока недоступно, если вы хотите поддерживать уровень API <11.

Обходным путем является использование onItemClickListener.

Настройка списка:

 listView = (ListView) timeline.findViewById(android.R.id.list); listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE); listView.setItemsCanFocus(false); listView.setAdapter(new ListAdapter(getActivity(), R.layout.cleaning_list_item, items)); 

Слушатель ListFragment или ListActivity:

 @Override public void onListItemClick(ListView l, View v, int position, long id) { SparseBooleanArray checked = listView.getCheckedItemPositions(); boolean hasCheckedElement = false; for (int i = 0; i < checked.size() && !hasCheckedElement; i++) { hasCheckedElement = checked.valueAt(i); } if (hasCheckedElement) { if (mMode == null) { mMode = ((SherlockFragmentActivity) getActivity()).startActionMode(new MyActionMode()); mMode.invalidate(); } else { mMode.invalidate(); } } else { if (mMode != null) { mMode.finish(); } } } 

Где MyActionMode - это реализация ActionMode.Callback:

 private final class MyActionMode implements ActionMode.Callback { /* ... */ } 
  • При проверке флажка в listview также проверяются другие случайные флажки
  • Цикл для загрузки изображений в виде списка по одному
  • Android: кнопка «Радио» в пользовательском списке
  • Пользовательский адаптер Listview с фильтром Android
  • Справка относительно события onClick () для элемента пользовательской строки списка ListView
  • Отображение текущего выбора в списке
  • Как реализовать поиск в CustomListView на основе classа classа POJO в Android?
  • Push Listview, когда клавиатура появляется без настройкиPan
  • Пользовательский getFilter в пользовательском ArrayAdapter в android
  • Как изменить цвет линии разделителя Android ListView?
  • notifyDataSetChanged () делает обновление списка и прокручивает подсказки назад
  • Давайте будем гением компьютера.