How to select an ListView item after long click?
It's possible, but just barely... I actually don't know how such a simple thing can wind up so ridiculously complicated.
The key to the answer can be found here: Android: keep blue background after ListView selection
What this boils down to is to define an additional style that is used by the ListView
and setting the choice mode to AbsListView.CHOICE_MODE_SINGLE
(as explained in the linked answer).
This allows you programmatically toggle the selection using Listview.setItemChecked()
. However, you need to keep track of the index of the touched item in the onItemLongClick
callback yourself, because ListView.setSelection()
won't do that (at least ListView.getSelectedItem()
will always return -1 as far as I can see).
Code (for simplicity, my fragment implements all three OnItemClickListener
, OnItemLongClickListener
, and ActionMode.Callback
):
@Overridepublic View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){ this.listViewAdapter = new ListViewAdapter(); this.root = (ListView)inflater.inflate(R.layout.fragment_bookmarks, container, false); this.root.setAdapter(this.listViewAdapter); this.root.setOnItemClickListener(this); this.root.setOnItemLongClickListener(this); this.root.setChoiceMode(AbsListView.CHOICE_MODE_SINGLE); return this.root;}@Overridepublic boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) { if(this.cabMode != null) return false; this.selectedPosition = position; this.root.setItemChecked(position, true); this.root.setOnItemClickListener(null); this.cabMode = getActivity().startActionMode(this); return true;}
And finally, if you want to get rid of the selection when the CAB is closed:
@Overridepublic void onDestroyActionMode(ActionMode mode) { cabMode = null; this.root.setItemChecked(this.selectedPosition, false); this.selectedPosition = -1; this.root.setOnItemClickListener(this);}
Registering and unregistering the OnItemClickListener
makes sure that while the CAB is active you won't accidentally trigger the action usually associated with the item (like opening a detail view).
My solution:(trick)
final ListView lvMain = (ListView) activity.findViewById(R.id.listTHEMES);lvMain.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);lvMain.setItemsCanFocus(false);ArrayAdapter<String> adapter = new ArrayAdapter<String>(activity, android.R.layout.simple_list_item_multiple_choice, ArrayTheme);lvMain.setAdapter(adapter);lvMain.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { @Override public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int pos, long id) { // TODO Auto-generated method stub if (lvMain.isItemChecked(pos)){lvMain.setItemChecked(pos,false);}else{lvMain.setItemChecked(pos,true);} Log.v(LOG_TAG,"long clicked pos: " + pos); //lvMain.setSelection(); return true; }});lvMain.setOnItemClickListener(new AdapterView.OnItemClickListener() { public void onItemClick(AdapterView<?> parent, View view, int position, long id) { //Log.d(LOG_TAG, "itemClick: position = " + position + ", id = " + id); if (lvMain.isItemChecked(position)){lvMain.setItemChecked(position,false);}else{lvMain.setItemChecked(position,true);} }});