android - ItemTouchHelper onMove 更新物品位置
问题描述
使用 itemTouchHelper onMove 方法时。如何根据列表中的位置使用编号列表。
例如,第 1 项、第 2 项、第 3 项等都基于该项目在列表中的实际位置。然后如何通过向上或向下拖动来移动项目。更新列表中的其余项目以反映其在列表中的正确位置?
我正在使用以下代码:
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
val fromPosition = viewHolder.adapterPosition
val toPosition = target.adapterPosition
Collections.swap(steps!!, fromPosition, toPosition)
recyclerView.adapter!!.notifyItemMoved(fromPosition,toPosition)
return true
}
片段:
视频:
更新(适配器代码):
val TAG:String = "StepAdapter"
var steps: MutableList<Step> = ArrayList()
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StepViewHolder {
return StepViewHolder(
LayoutInflater.from(parent.context)
.inflate(R.layout.recipe_property_step_list_item, parent, false))
}
override fun getItemCount(): Int{
return steps.size
}
override fun onBindViewHolder(holder: StepViewHolder, position: Int) {
holder.bind(steps.get(position), position)
Log.i(TAG,"onBindViewHolder - ${steps.get(position)}")
}
override fun onBindViewHolder(holder: StepViewHolder, position: Int, payloads: MutableList<Any>) {
Log.i(TAG,"onBindViewHolder - Payloads - $payloads")
val text:String = StringBuilder("${position + 1}.) ${steps[position].text}").toString()
Log.i(TAG,"onBindViewHolder - Text - $text")
holder.st_text.text = text
}
fun updateSteps(newSteps: MutableList<Step>){
val diffResult = DiffUtil.calculateDiff(StepDiffCallBack(this.steps,newSteps))
this.steps.clear()
this.steps.addAll(newSteps)
notifyDataSetChanged()
diffResult.dispatchUpdatesTo(this)
}
日志:
2020-04-12 16:57:21.787 15808-15808/com.keep.recipeapp I/StepAdapter: onBindViewHolder - Payloads - []
2020-04-12 16:57:21.787 15808-15808/com.keep.recipeapp I/StepAdapter: onBindViewHolder - Text - 1.) Prepping the kitchen sink
2020-04-12 16:57:21.789 15808-15808/com.keep.recipeapp I/StepAdapter: onBindViewHolder - Payloads - []
2020-04-12 16:57:21.789 15808-15808/com.keep.recipeapp I/StepAdapter: onBindViewHolder - Text - 2.) prep the nuts and bolts
2020-04-12 16:57:21.791 15808-15808/com.keep.recipeapp I/StepAdapter: onBindViewHolder - Payloads - []
2020-04-12 16:57:21.791 15808-15808/com.keep.recipeapp I/StepAdapter: onBindViewHolder - Text - 3.) Cook the kitchen sink
测试数据
解决方案
实现这一点的唯一方法是重新绑定您ViewHolder
的 s 以便他们TextView
的 s 显示更改的位置。但是调用notifyDataSetChanged()
ornotifyItemRangeChanged(0, pos)
会让你所有的物品淡出淡入,因为它们都被重新绑定了,我不建议这样做,因为它非常丑陋(但它仍然可以工作)
你用过方法onBindViewHolder(holder: ViewHolder, position: Int, payloads: MutableList<Any>)
吗?这允许仅更新View
您内部的一些 sViewHolder
而无需重新绘制整个s View
,因此您的更改RecyclerView
将更加平滑。
在您的onMove
方法中,您调用notifyItemRangeChanged
提供应该更新的项目的范围,并提供 Any() 作为有效负载,因为重新绑定视图不需要额外的信息,因为您可以在适配器的方法中访问位置和数据。
override fun onMove(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder): Boolean {
val fromPosition = viewHolder.adapterPosition
val toPosition = target.adapterPosition
Collections.swap(steps!!, fromPosition, toPosition)
recyclerView.adapter!!.notifyItemMoved(fromPosition,toPosition)
recyclerView.adapter!!.notifyItemRangeChanged(0, max(fromPosition, toPosition), Any())
// as you dont need to change items that are below the maximum positions
// their positions will be correct
return true
}
请记住,super
如果有效负载为空,您应该调用方法。
override fun onBindViewHolder(holder: MyViewHolder, position: Int, payloads: MutableList<Any>) {
if (payloads.isEmpty()) super.onBindViewHolder(holder, position, payloads)
else {
holder.theTextView.text = "$position.)${myList[position].data}"
}
}
更新
你确定你打电话notifyItemRangeChanged(min(fromPos, toPos), max(fromPos,toPos)
?这件事将要求onBindViewHolder
范围内的每个项目。您应该在调用后调用它notifyItemMoved
。当它工作时,尝试将对象作为有效负载传递。
日志不显示行为,它似乎是适配器在初始化后绑定视图时的输出。
推荐阅读
- python-3.x - 如何在 Beautiful Soup 中只包含指定的类而不包含子类?
- javascript - 测试扩展类时的 ES6 基类(超级方法)的玩笑模拟方法
- html - 引导菜单和汉堡包在一起
- python - matplotlib/seaborn 中时间直方图中的轴刻度
- c++ - 如何在 Windows 上使用 CreateFile 创建带有 LPSECURITY_ATTRIBUTES 的文件?
- javascript - 错误:找不到导航器的任何屏幕。您是否将任何屏幕定义为其子级?
- auth0 - 通过 Web UI 从 Auth0 导出应用程序和 API 设置
- mysql - 如何判断SQL查询的复杂度
- java - java opencv内存不足错误如何解决?
- javascript - 按某个单词对列表进行排序