6

I have a listview registered for context menu in multiple choice mode:

private void initListViewForContextMenu(){
    log.d("FilesFragment", "initListViewForContextMenu()");
    ListView listView = getListView();
    listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
    listView.setMultiChoiceModeListener(new MultiChoiceModeListener() { ...

The problem is that not all the items of my view should be selectable, only those showing a special icon should be available for selection. I don't know how to implement this, I've defined an OnItemLongClickListener:

getListView().setOnItemLongClickListener(new OnItemLongClickListener() {
    @Override
    public boolean onItemLongClick(AdapterView<?> adapter, View view, int position, long id) {
        Log.d("FilesFragment", "OnItemLongClickListener.onItemLongClick at pos " + position);
        PfmDocument doc = (PfmDocument)adapter.getItemAtPosition(position);
        if (doc.isOnBasket()){
            Log.d("FilesFragment", "OnItemLongClickListener.onItemLongClick detected in basket");
            ListView lv = (ListView) adapter;
            lv.setItemChecked(position, false);
        }
        return false;
        }
    }); 

but this listener is never called.

I've also tried to set an OnLongClickListener to the row view in the adapter, but doing this normal click is also disable even when context menu is closed (not in selection mode).

if (doc.isOnBasket()){
    rowView.setOnLongClickListener(new OnLongClickListener() {
    @Override
    public boolean onLongClick(View v) {
        return false; // do nothing, already in basket
    }
});

// }

Patricia
  • 7,752
  • 4
  • 37
  • 70
jmhostalet
  • 4,399
  • 4
  • 38
  • 47
  • Do you want the row with the special icon to be selectable or have a context menu (or both)? – Sam Jan 21 '13 at 21:03
  • I need all the rows clickable in order to open a properties view, but only those rows with the special icon selectable with a long click (multiple selection within a context menu). Once the multiple selection has been started only those rows with the special icon may be clicked to add tehm to the basket. The special icon shows actually that the item is available for putting it in the basket and that it is not already in it, in other words, all items are clickable to see their details, but only which are not already in the basket may be selected for putting them into the basket. Hope I'm clear. – jmhostalet Jan 22 '13 at 17:16

1 Answers1

10

If you dig into the android sourcecode (AbsListview), you will see that setting the choiceMode to MULTIPLE_MODAL will take over the longpress. That is why your listener is never called.

You can decide whether a view is clickable by return true/false in isEnabled(position) in your adapter.

The code below only solves the part where during the actionmode, the items that are already added to the basket are not clickable.

But it should be fairly easy to just uncheck the item that is longpressed if it's not a valid item.

Hope this help!

In your MultiChoiceModeListener:

@Override
public boolean onCreateActionMode(ActionMode mode, Menu menu)
{
    this.adapter.setActionMode(true);
    return true;
}

@Override
public void onDestroyActionMode(ActionMode mode)
{
    this.adapter.setActionMode(false);
}

And then in your custom adapter:

public abstract class AbstractCollectionAdapter extends AbstractCursorAdapter
{
    private boolean isActionMode;

    public AbstractCollectionAdapter(Context context)
    {
        super(context);

        this.isActionMode = false;
    }

    @Override
    public boolean isEnabled(int position)
    {
        if (this.isActionMode)
        {
            final Object item = this.getItem(position);
            if (!item.isInBasket())
            {
                //only enable items that are not inside the basket
                return true;
            }
            //all other items are disabled during actionmode
            return false;
        }
        //no actionmode = everything enabled
        return true;
    }

    public void setActionMode(boolean isActionMode)
    {
        this.isActionMode = isActionMode;
    }
}
Jelle
  • 919
  • 9
  • 16
  • Hi, I encountered with the same problem as Jim and I can't use the AbstractCursorAdapter because it's not defined in the android library and I can't use the CursorAdapter either because I'm not getting my vaules from database source, I'm generating my list from a ArrayList. I have my custom adapter which I extend BaseAdapter. Is there a possible way for me to use this method in my custom adapter without using cursor adapter? – Esat IBIS Jun 29 '16 at 19:24
  • @Jelle : `isInBasket()` - Requesting , please explain it's uses. – Vikrant Jan 07 '17 at 12:27
  • 1
    @Vikrant: just replace that line with a method that returns whether or not your item is selected at this time. – Jelle Jan 10 '17 at 10:59
  • @EsatIBIS : of course you can! Just extend BaseAdapter. – Jelle Jan 10 '17 at 10:59