ListView OnItemLongClickListener() not triggered

android, contextual-action-bar, java, listview

Solution

When using a ListActivity or ListFragment there is no method you can override for the long-click, and getting access to the ListView is not possible in onCreateView(), since it is being controlled by the parent class.

So, to overcome this, I did this, since the getListView() command won't work until after the view is created:

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);
    mRecipeListView = this.getListView();
    mRecipeListView.setOnItemLongClickListener(new ListView.OnItemLongClickListener() {

        @Override
        public boolean onItemLongClick(AdapterView<?> arg0, View view, int position, long row_id) {
            // Process the long-click
        }
    });
}

Problem

I have a class that extends ListActivity where the list items respond to OnClick events. Adding an OnItemLongClickListener does not work. The onItemLongClick() function is not called (no log-output or Toast showing) but the normal OnClick() event is handled instead. I want to display a contextual action bar upon long click. A minimum example using my code in a new project works fine. So my question is: What can possibly prevent the onItemLongClick() trigger from being triggered? My minimum API is 11. I am also setting the listView to `longClickable="true"`. Activity code (selected functions): ``` public class EventListActivity extends ListActivity { private ArrayList<Event> arrEvents = null; private ArrayAdapter<Event> adpEvents = null; private ActionMode mActionMode = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // only create list adapter and set it arrEvents = new ArrayList<Event>(); adpEvents = new ArrayAdapter<Event>(this, android.R.layout.simple_list_item_activated_2, android.R.id.text1, arrEvents) { @Override public View getView(int position, View convertView, ViewGroup parent) { View view = super.getView(position, convertView, parent); TextView text1 = (TextView) view.findViewById(android.R.id.text1); TextView text2 = (TextView) view.findViewById(android.R.id.text2); text1.setText(arrEvents.get(position).getTitle()); text2.setText(arrEvents.get(position).getDateTimeFormatted()); return view; } }; setListAdapter(adpEvents); // add CAB to ListView setupCAB(); } @Override protected void onResume() { super.onResume(); // populate list and refresh adapter createEventList(); adpEvents.notifyDataSetChanged(); // if list empty show emtpy msg, otherwise hide it setContentView(R.layout.activity_event_list); TextView empty = (TextView) findViewById(R.id.text_empty); if(arrEvents.isEmpty()) { empty.setVisibility(View.VISIBLE); } else { empty.setVisibility(View.GONE); } } private void setupCAB() { // Important: to select single mode getListView().setChoiceMode(ListView.CHOICE_MODE_SINGLE); getListView().setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { // Called when the user long-clicks an item on the list @Override public boolean onItemLongClick(AdapterView<?> parent, View row, int position, long rowid) { Log.w("EventListActivity", "Long click detected!"); Toast.makeText(EventListActivity.this, "Long click detected!", Toast.LENGTH_SHORT).show(); if (mActionMode != null) { return false; } // Important: to mark the editing row as activated getListView().setItemChecked(position, true); // Start the CAB using the ActionMode.Callback defined above mActionMode = EventListActivity.this.startActionMode(mActionModeCallback); return true; } }); } private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() { // Called when the action mode is created; startActionMode() was called @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { // Inflate a menu resource providing context menu items MenuInflater inflater = mode.getMenuInflater(); inflater.inflate(R.menu.event_context, menu); return true; } // Called when the user enters the action mode @Override public boolean onPrepareActionMode(ActionMode mode, Menu menu) { // Disable the list to avoid selecting other elements while editing one EventListActivity.this.getListView().setEnabled(false); return true; // Return false if nothing is done } // Called when the user selects a contextual menu item @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { switch (item.getItemId()) { case R.id.mnu_share_event: //TODO share event mode.finish(); return true; default: return false; } } // Called when the user exits the action mode @Override public void onDestroyActionMode(ActionMode mode) { // Re-enable the list after edition EventListActivity.this.getListView().setEnabled(true); mActionMode = null; } }; } ``` activity_event_list.xml: ``` <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context=".EventListActivity" > <TextView android:id="@+id/text_empty" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_alignParentTop="true" android:layout_centerHorizontal="true" android:layout_marginTop="45dp" android:text="@string/empty" android:textAppearance="?android:attr/textAppearanceLarge" android:visibility="gone" /> <ListView android:id="@android:id/list" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_alignParentLeft="true" android:layout_alignParentTop="true" android:longClickable="true" > </ListView> </RelativeLayout> ```

Original source

Related problems