我正在构建一个应用程序,允许用户从RecyclerView列表中进行选择,突出显示他们的选择。问题在于,为了第一次突出显示一个项目,需要长按。 (然后,只需单击即可进行选择。)
我没有在文档中找到任何内容来说明为什么会发生这种情况。
我正在使用SelectionTracker
具体遵循此guide
以下是代码: https://github.com/marcosholgado/multiselection
期望: 我希望每次有人短按RecyclerView上的项目。
现实: 为了第一次选择一个项目,用户需要长按它。
有什么想法吗?
答案 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)
虽然我想不出不涉及重新实现MotionInputHandler
和SelectionTracker.Builder
(如本指南中所述)的解决方案,但是有一个巧妙的技巧可以实现您的行为想要。
我们知道TouchInputHandler
只要不为空,就单击一次即可选择项目。这意味着,如果我们在SelectionTracker
中保存了一些与真实列表项不相关的特殊键,则实际上我们是通过这种方式“激活”了单击选择模式。但是,我们还必须确保SelectoinTracker
没有提供相同的特殊密钥来保持数据的一致性。
因此,假设您已经选择了一个特殊键,例如KeyProvider
,则激活和停用选择模式现在只需调用ghostKey
或mSelectionTracker.select(ghostkey)
。然后,您可以根据自己的喜好执行这些调用,只需拥有一个可激活和停用选择模式的按钮,或者在宿主视图创建过程中即简单地调用mSelectionTracker.clearSelection()
,onCreate
等即可。
如果您使用的是Kotlin,还可以定义一些扩展来为您包装这些调用,因此您可以执行onCreateView
或mSelectionTracker.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'])