在多选模式下启用/禁用列表视图中的项目选择

时间:2013-01-21 19:59:09

标签: android android-listview android-contextmenu

我在多选模式下为上下文菜单注册了listview:

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

问题是我的视图中并非所有项目都可以选择,只有那些显示特殊图标的项目才可供选择。我不知道如何实现这一点,我已经定义了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;
        }
    }); 

但是从不调用此监听器。

我还尝试将OnLongClickListener设置为适配器中的行视图,但即使关闭上下文菜单(不在选择模式下),也会禁用此正常点击。

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

//}

1 个答案:

答案 0 :(得分:10)

如果你深入了解android源代码(AbsListview),你会发现将choiceMode设置为MULTIPLE_MODAL将接管longpress。这就是为什么你的听众永远不会被召唤的原因。

您可以通过适配器中的isEnabled(position)返回true / false来决定是否可以查看视图。

以下代码仅解决了在动作模式中已添加到购物篮中的商品无法点击的部分。

但如果它不是有效的项目,那么取消选中长按的项目应该相当容易。

希望这有帮助!

在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);
}

然后在您的自定义适配器中:

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;
    }
}