如何使用RecyclerView的SelectionTracker无需长按即可选择第一项

时间:2019-04-03 11:57:23

标签: java android android-recyclerview

我正在构建一个应用程序,允许用户从RecyclerView列表中进行选择,突出显示他们的选择。问题在于,为了第一次突出显示一个项目,需要长按。 (然后,只需单击即可进行选择。)

我没有在文档中找到任何内容来说明为什么会发生这种情况。

我正在使用SelectionTracker

具体遵循此guide

以下是代码https://github.com/marcosholgado/multiselection

期望: 我希望每次有人短按RecyclerView上的项目。

现实: 为了第一次选择一个项目,用户需要长按它。

有什么想法吗?

6 个答案:

答案 0 :(得分:7)

只需覆盖SelectionHotspot即可返回true。这就是您所需要的

fun getItemDetails(): ItemDetailsLookup.ItemDetails<Long> =
            object : ItemDetailsLookup.ItemDetails<Long>() {
                override fun getPosition(): Int = adapterPosition
                override fun getSelectionKey(): Long? = itemId
                override fun inSelectionHotspot(e: MotionEvent): Boolean { return true }
            }

答案 1 :(得分:2)

虽然我想不出不涉及重新实现MotionInputHandlerSelectionTracker.Builder(如本指南中所述)的解决方案,但是有一个巧妙的技巧可以实现您的行为想要。

我们知道TouchInputHandler只要不为空,就单击一次即可选择项目。这意味着,如果我们在SelectionTracker中保存了一些与真实列表项不相关的特殊键,则实际上我们是通过这种方式“激活”了单击选择模式。但是,我们还必须确保SelectoinTracker没有提供相同的特殊密钥来保持数据的一致性。

因此,假设您已经选择了一个特殊键,例如KeyProvider,则激活和停用选择模式现在只需调用ghostKeymSelectionTracker.select(ghostkey)。然后,您可以根据自己的喜好执行这些调用,只需拥有一个可激活和停用选择模式的按钮,或者在宿主视图创建过程中即简单地调用mSelectionTracker.clearSelection()onCreate等即可。

如果您使用的是Kotlin,还可以定义一些扩展来为您包装这些调用,因此您可以执行onCreateViewmSelectionTracker.enable()

之类的操作。

答案 2 :(得分:0)

这就是我所做的:

binding.root.setOnClickListener {
   tracker?.let {
     if(!it.hasSelection()) it.select(binding.currItem?.uuid!!)
        binding.setVariable(BR.selected, it.isSelected(binding.currItem?.uuid))
     }

     binding.executePendingBindings()
}

我在视图上实现了单击侦听器,并检查了选择跟踪器是否具有任何选定的实体。如果没有任何选择,则我明确添加了选择,选择跟踪器将自动启用。

我认为这必须是您正在寻找的解决方案。

答案 3 :(得分:0)

使用此行

selectionTracker.select(item.getSelectionKey());

关于此替代方法

 .withOnItemActivatedListener(new OnItemActivatedListener() {
                @Override
                public boolean onItemActivated(@NonNull ItemDetailsLookup.ItemDetails item, @NonNull MotionEvent e) {
                    selectionTracker.select(item.getSelectionKey());
                    return true;
                }
            })

我这样解决了。继续编码。

答案 4 :(得分:0)

RecyclerView-selection 框架不是为处理以下任一场景而设计的!!

A.) 一个“启用多选”按钮,用于打开和关闭多选。

*如果您的范围需要 A.) 或 B.)(以上),请勿使用 RecyclerView-selection 框架。

改为将其删除并执行以下操作:

1.) 将 Post-Api 数据字段添加到您的列表项模型:

var isMultiSelected: Boolean = false // User has highlighted this inbox's row for multi-selection

2.) 创建一个监听器来从 Adapter 到 Fragment/Activity 进行通信:

class MyFragment : MyFragmentListener {
interface MyFragmentListener {
    fun myDataModelOnClick(myDataModel: MyDataModel)
    fun engageMultiSelect(selectedDataModelCount: Int)
    fun disengageMultiSelect()
}
override fun engageMultiSelect(selectedMyModelCount: Int) {
    // Update the fragment view for multi-select engaged conditions
    selectedCount_textView.text = selectedMyModelCount.toString()
}

override fun disengageMultiSelect() {
// Update the fragment view for multi-select engaged conditions
}

3.) 更新您的 Adapter.onBindViewHolder() 以使用新字段

holder.enableMultiSelectionButton.setOnClickListener {
    myModel.isMultiSelected = true
    myModel.engageMultiSelect(getMultiSelectionCount()) // Enable multi-selection
    notifyItemChanged(position)
}
holder.rowConstraintLayout.setOnClickListener {
    if (getMultiSelectionCount() > 0) { // Is multi-selection engaged?
        myModel.isMultiSelected = !myModel.isMultiSelected
        if (getMultiSelectionCount() > 0) { // New Item Count may still be larger than 0
            myModelListener.engageMultiSelect(getMultiSelectionCount())
        } else {
            myModelListener.disengageMultiSelect()
        }
        notifyItemChanged(position)
    } else {
        // Normal 'tap' when multi-selection is not engaged
    }
}
holder.rowConstraintLayout.setOnLongClickListener {
    myModel.isMultiSelected = !myModel.isMultiSelected
    if (getMultiSelectionCount() > 0) { // Is multi-selection engaged?
        myModelListener.engageMultiSelect(getMultiSelectionCount())
    } else {
        myModelListener.disengageMultiSelect()
    }
    notifyItemChanged(position)
    true
}
if (myModel.isMultiSelected) {
    holder.rowConstraintLayout.setBackgroundColor(R.id.coolcolor)
} else {
    holder.rowConstraintLayout.setBackgroundColor(R.id.white)
}

答案 5 :(得分:0)

在您的 ViewHolder 中,设置 SelectionTracker.hasSelection() 并在其中使用 SelectionTracker.select(getItemDetails().getSelectionKey()) 检查您是否有任何选定的项目,如果返回 false,只需使用 itemView.setOnClickListener(v -> { if (!tracker.hasSelection()) tracker.select(getItemDetails().getSelectionKey()); }); 选择该项目 像这样:

model.add(Dense(16, activation='relu'))
model.add(Dense(4, activation='softmax'))
model.compile(optimizer='adam',
          loss='categorical_crossentropy',
          metrics=['accuracy'])