长按后如何选择ListView中的项目?

15

我有一个小问题。我已经将ListFragment注册为其自身ListViewOnItemClickListenerOnItemLongClickListener

当调用onItemClick事件时,会启动该项的详细视图活动的意图,没有问题。

onItemLongClick事件发生时,我想要实现以下几件事情:

  • 创建CAB
  • 保持长按的项目处于选定状态

代码:

@Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
    if(this.cabMode != null)
        return false;
    this.cabMode = getActivity().startActionMode(editModeCallback);
    view.setSelected(true);
    return true;
}

然而,CAB将显示选择不会停留在该项上。

如果有关联的话,以下是一些细节:我已经阅读了使用view.requestFocusFromTouch()或使用listView.setItemChecked()调用来解决此问题,但这对我没用。此外,列表项的视图是从自定义布局实例化的,但没有附加任何自定义事件侦听器。

任何帮助都将不胜感激。谢谢!


长按后传递所选项目的位置。 - kyogs
我应该把它传递到哪里?listView.setItemChecked()需要一个位置参数,但调用它没有效果。 - Chris
1
你是否执行了 ListView.setChoiceMode(...)?如果找不到解决方法,你可以像这里(http://goo.gl/7aQAn)一样手动选择。 - codinguser
没有,谢谢你的指点。我已经尝试了几种选择模式的组合,使用listView.setItemChecked()view.setSelected()方法进行调用,但是仍然没有效果。我会看一下Sherlock代码,不过我认为我所尝试的东西非常基础,应该有一种简单的方法来实现它。 - Chris
2个回答

8
这是可能的,但只是勉强能实现……我实际上不知道为什么如此简单的事情会变得如此复杂。
答案的关键在于这里:Android: keep blue background after ListView selection 这意味着要定义一个额外的样式,该样式由ListView使用,并将选择模式设置为AbsListView.CHOICE_MODE_SINGLE(如链接答案中所述)。
这允许您通过Listview.setItemChecked()以编程方式切换选择。但是,您需要自己在onItemLongClick回调中跟踪触摸项目的索引,因为ListView.setSelection()不会这样做(至少ListView.getSelectedItem()总是返回-1,据我所见)。
代码(为简单起见,我的片段实现了所有三个OnItemClickListener,OnItemLongClickListener和ActionMode.Callback):
@Override
public 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;
}

@Override
public 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;
}

最后,如果您想在关闭CAB时取消选择,请执行以下操作:
@Override
public void onDestroyActionMode(ActionMode mode) {
    cabMode = null;
    this.root.setItemChecked(this.selectedPosition, false);
    this.selectedPosition = -1;
    this.root.setOnItemClickListener(this);
}

注册和注销OnItemClickListener可以确保在CAB处于活动状态时,您不会意外触发通常与该项相关的操作(例如打开详细视图)。


Chris,注意你实际上不需要跟踪所选项目的索引。如果在choiceMode="singleChoice"中,则使用AbsListView.getCheckedItemPosition()。如果在choiceMode="multipleChoice"中,则使用AbsListView.getCheckedItemPositions()来获取已选项目集合。(请注意,此方法也适用于单选模式,但另一种方法更简单。) - stormin986
哦,谢谢你的信息!我太专注于 ListView.getSelectedItem() 了 :-) - Chris

1
我的解决方案:(技巧)
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);}

    }
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接