Search code examples
androidlistviewonitemlongclicklistener

Selecting multiple items in list using setOnItemLongClickListener


I have a list of messages in an Android listview. I want to delete the messages from the list on press of Long Click. I have declared all the states in my list-selector but still on long press. The particular item in the list does not remain focused or selected after long press. I tried setting the view.setselected(true), which isn't working either. Am I doing something wrong?

This is my list_selector.

<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item 
 android:state_selected="false"
    android:state_pressed="false" 
    android:drawable="@drawable/row_item_image" />
<item android:state_pressed="true" 
    android:drawable="@drawable/row_item_hover_image" />
<item android:state_focused="true" 
    android:drawable="@drawable/row_item_hover_image" />
<item android:state_selected="true" 
    android:drawable="@drawable/row_item_hover_image" />
</selector>

And this is my listener interface:

listview.setOnItemLongClickListener(new OnItemLongClickListener() 
{

    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long arg3) {
        // TODO Auto-generated method stub
        //view.setSelected(true);
        if(view.isPressed())
        {
        view.setSelected(true);
        }
        return false;
    }
});

Solution

  • You don`t need to implement OnItemLongClickListener because ListView itself has such functionality what you want.Try this on your activity:

    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
        listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
    
            @Override
            public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
                // TODO Auto-generated method stub
                return false;
            }
    
            @Override
            public void onDestroyActionMode(ActionMode mode) {
                editListAdapter.removeSelection();
    
            }
    
            @Override
            public boolean onCreateActionMode(ActionMode mode, Menu menu) {
                mode.getMenuInflater().inflate(R.menu.delete_action_mode, menu);
                return true;
            }
    
            @Override
            public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
                switch (item.getItemId()) {
                case R.id.delete_mode:
                    SparseBooleanArray selected = editListAdapter.getSelectedIds();
                    for (int i = (selected.size() - 1); i >= 0; i--) {
                        if (selected.valueAt(i)) {
                            User selectedItem = editListAdapter.getItem(selected.keyAt(i));
                            editListAdapter.remove(selectedItem);
                        }
                    }
                    mode.finish();
                    return true;
                default:
                    return false;
                }
            }
    
            @Override
            public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
                    boolean checked) {
                int checkedCount = listView.getCheckedItemCount();
                mode.setTitle(checkedCount + " selected");
                editListAdapter.toggleSelection(position);
            }
        });
    

    Your ArrayAdapter Class would be like this:

    public class UserListAdapter extends ArrayAdapter<User> {
    
    LayoutInflater inflater;
    private int resId;
    private TextView userPosition, userName, userLogin, userPassw, userStatus, userRole;
    private SparseBooleanArray mSelectedItemsIds;
    private List<User> userList;
    
    public UserListAdapter(Context context, int resource, List<User> users) {
        super(context, resource, users);
        this.resId = resource;
        this.inflater = LayoutInflater.from(context);
        this.userList = users;
        mSelectedItemsIds = new SparseBooleanArray();
    }
    
    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        User user = getItem(position);
        UserItemHelper helper;
        if (convertView == null) {
            convertView = inflater.inflate(resId, parent, false);
            userPosition = (TextView) convertView.findViewById(R.id.user_item_position);
            userName = (TextView) convertView.findViewById(R.id.user_item_name);
            userLogin = (TextView) convertView.findViewById(R.id.user_item_login);
            userPassw = (TextView) convertView.findViewById(R.id.user_item_passw);
            userStatus = (TextView) convertView.findViewById(R.id.user_item_status);
            userRole = (TextView) convertView.findViewById(R.id.user_item_role);
            helper = new UserItemHelper(userPosition, userName, userLogin, userPassw, userStatus, userRole);
            convertView.setTag(helper);
        } else {
            helper = (UserItemHelper)convertView.getTag(); 
        }
        helper.getPosition().setText(position + 1 + "");
        helper.getName().setText(user.getName());
        helper.getLogin().setText(user.getLogin());
        helper.getPassw().setText(user.getPassw());
        helper.getStatus().setText(user.getStatus() +"");
        helper.getRole().setText(user.getRole()+"");
        return convertView;
    }
    
    public ArrayList<String> getItemsName() {
        ArrayList<String> names = new ArrayList<String>();
        for (int i = 0; i < getCount(); i++) {
            names.add(getItem(i).getName().toLowerCase());
        }
        return names;
    }
    
    @Override
    public void remove(User object) {
        // TODO Auto-generated method stub
        super.remove(object);
    }
    
    public void toggleSelection(int position) {
        selectView(position, !mSelectedItemsIds.get(position));
    }
    
    public void removeSelection() {
        mSelectedItemsIds = new SparseBooleanArray();
        notifyDataSetChanged();
    }
    
    private void selectView(int position, boolean value) {
        if (value)
            mSelectedItemsIds.put(position, value);
        else
            mSelectedItemsIds.delete(position);
        notifyDataSetChanged();
    
    }
    
    public SparseBooleanArray getSelectedIds() {
        return mSelectedItemsIds;
    
    }
    

    }

    Also create menu xml.

      <?xml version="1.0" encoding="utf-8"?>
      <menu xmlns:android="http://schemas.android.com/apk/res/android" >
    
          <item
             android:id="@+id/delete_mode"
             android:icon="@drawable/delete"
             android:title="@string/delete_text"/>
    
       </menu>