如何在长按后选择ListView项目?

Chr*_*ris 14 android selection android-listview onitemclicklistener contextual-action-bar

我有一个愚蠢的小问题.我已经注册了一个ListFragment既作为OnItemClickListenerOnItemLongClickListener自身ListView.

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;
}
Run Code Online (Sandbox Code Playgroud)

然而,CAB将显示选择不会留在项目中.

一些零碎的东西,如果它们是相关的:我已经读过关于通过调用view.requestFocusFromTouch()或使用修复此问题listView.setItemChecked(),但这对我不起作用.此外,列表项的视图是从自定义布局实例化的,但没有附加任何自定义事件侦听器.

任何帮助表示赞赏.谢谢!

Chr*_*ris 8

这是可能的,但几乎......我实际上不知道这么简单的事情怎么会变得如此荒谬复杂.

答案的关键可以在这里找到:Android:在ListView选择后保持蓝色背景

这可以归结为定义一个额外的样式,ListView并将选择模式设置为AbsListView.CHOICE_MODE_SINGLE(如链接的答案中所述).

这允许您使用编程方式切换选择Listview.setItemChecked().但是,您需要自己跟踪onItemLongClick回调中触摸项的索引,因为ListView.setSelection()不会这样做(至少ListView.getSelectedItem()在我看到的时候总是返回-1).

代码(为简单起见,我的片段实现了所有三个OnItemClickListener,OnItemLongClickListenerActionMode.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;
}
Run Code Online (Sandbox Code Playgroud)

最后,如果你想在CAB关闭时摆脱选择:

@Override
public void onDestroyActionMode(ActionMode mode) {
    cabMode = null;
    this.root.setItemChecked(this.selectedPosition, false);
    this.selectedPosition = -1;
    this.root.setOnItemClickListener(this);
}
Run Code Online (Sandbox Code Playgroud)

注册和取消注册OnItemClickListener确保在CAB处于活动状态时,您不会意外触发通常与项目关联的操作(如打开详细视图).