Я внедряю recyclerView с возможностью изменения порядка товаров. Для этого я использую ItemTouchHelper. Вот мой код:
interface ItemTouchHelperAdapter {
fun onItemMove(fromPosition: Int, toPosition: Int) : Boolean
fun onItemDismiss(position: Int)
}
и вспомогательный класс, реализующий этот интерфейс
class ItemTouchHelperCallback(private val adapter: ItemTouchHelperAdapter) : ItemTouchHelper.Callback() {
override fun isLongPressDragEnabled(): Boolean {
return true
}
override fun isItemViewSwipeEnabled(): Boolean {
return true
}
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
val swipeFlags = ItemTouchHelper.START or ItemTouchHelper.END
return makeMovementFlags(dragFlags, swipeFlags)
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
adapter.onItemMove(viewHolder.adapterPosition, target.adapterPosition)
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
adapter.onItemDismiss(viewHolder.adapterPosition)
}
}
Кроме того, вот мой настраиваемый адаптер recyclerView
class ScansOrderAdapter(private val scans: MutableList<Scan>) :
RecyclerView.Adapter<ScansOrderAdapter.ViewHolder>(), ItemTouchHelperAdapter {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
return ViewHolder(
LayoutInflater.from(parent.context).inflate(
R.layout.item_change_order,
parent,
false
)
)
}
override fun getItemCount(): Int {
return scans.size
}
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
Glide.with(holder.itemView.item_image.context)
.load(scans[position].filePath)
.diskCacheStrategy(DiskCacheStrategy.NONE)
.skipMemoryCache(true)
.into(holder.itemView.item_image)
}
class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView)
override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
Collections.swap(scans, fromPosition, toPosition)
notifyItemMoved(fromPosition, toPosition)
return true
}
override fun onItemDismiss(position: Int) {
if(scans.size != 0) {
scans.removeAt(position)
notifyItemRemoved(position)
}
}
}
И, наконец, я Я устанавливаю адаптер, менеджер макета и ItemTouchHelper:
fragment_change_scans_recycler.layoutManager = LinearLayoutManager(requireContext(),
LinearLayoutManager.VERTICAL,
false)
val adapter = ScansOrderAdapter(scans)
fragment_change_scans_recycler.adapter = ScansOrderAdapter(scans)
val callback: ItemTouchHelper.Callback = ItemTouchHelperCallback(adapter)
val touchHelper = ItemTouchHelper(callback)
touchHelper.attachToRecyclerView(fragment_change_scans_recycler)
В результате я могу перемещать свои элементы и проводить их, все обратные вызовы работают, я проверил это, войдя в систему, НО, по некоторым причинам другие элементы делает не обновляет свои позиции и не заменяет. Я предлагаю что-то не так с notifyItemMoved(fromPosition, toPosition)
, может быть, я что-то забыл или не установил некоторые обязательные атрибуты.