0

First time messing with this TouchHelper, apologies. I just want to be able to move the same item twice without navigating to another activity to refresh the recyclerview. I assume I just don't know which 'notify' to use for the adapter.

After moving an item vertically (swiping is disabled intentionally), I am unable to move the item again. It visually may swap text with an item if I try to move it for a split second, but it reverts back and doesn't show the visual animation that I have the item selected. It also doesn't update the database.

Main Activity:

    override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityHuntsBinding.inflate(layoutInflater)
    setContentView(binding.root)

    auth = FirebaseAuth.getInstance()

    // This will be used to connect the RecyclerView, adapter, and viewModel together
    val viewModel: HuntViewModel by viewModels()
    viewModel.getHunts().observe(this) { huntsList ->
        binding.huntsRecyclerView.adapter = HuntAdapter(this, huntsList, this)

        val adapter = binding.huntsRecyclerView.adapter as? HuntAdapter
        val itemTouchHelperCallback = adapter?.let { HuntItemTouchHelperCallback(it) }
        val itemTouchHelper = itemTouchHelperCallback?.let { ItemTouchHelper(it) }
        itemTouchHelper?.attachToRecyclerView(binding.huntsRecyclerView)
    }

Adapter:

    override fun onItemMove(fromPosition: Int, toPosition: Int): Boolean {
    // Swap the items in the list
    Collections.swap(hunts, fromPosition, toPosition)

    // Update the sort order values for the affected items
    for (i in hunts.indices) {
        hunts[i].sortOrder = i + 1
    }

    // Notify the adapter of the item movement
    notifyItemMoved(fromPosition, toPosition)

    return true
}

override fun onItemRelease() {
    auth = FirebaseAuth.getInstance()

    val db = FirebaseFirestore.getInstance().collection(auth.currentUser.uid)
    val batch = db.firestore.batch()
    for (hunt in hunts) {
        batch.update(db.document(hunt.created!!), "sortOrder", hunt.sortOrder)
    }
    batch.commit()
        .addOnSuccessListener {
            Log.w("DB_Response", "Sort order updated successfully for all hunts.")
        }
        .addOnFailureListener { e ->
            Log.w("DB_Response", "Error updating sort order for all hunts.", e)
        }
}

TouchHelper Class:

class HuntItemTouchHelperCallback(private val listener: ItemTouchHelperListener) : 

ItemTouchHelper.Callback() {

interface ItemTouchHelperListener {
    fun onItemMove(fromPosition: Int, toPosition: Int): Boolean
    fun onItemRelease()
}

override fun isLongPressDragEnabled(): Boolean {
    return true
}

override fun isItemViewSwipeEnabled(): Boolean {
    return false
}

override fun getMovementFlags(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder
): Int {
    val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN
    return makeMovementFlags(dragFlags, 0)
}

override fun onMove(
    recyclerView: RecyclerView,
    viewHolder: RecyclerView.ViewHolder,
    target: RecyclerView.ViewHolder
): Boolean {
    return listener.onItemMove(viewHolder.adapterPosition, target.adapterPosition)
}

override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
}

override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) 
{
    super.clearView(recyclerView, viewHolder)
    listener.onItemRelease()
}
}
  • Have you tried only replacing the items in the adapter rather than making an entirely new adapter when the items change? One way to do this is to inject the flow of hunts into the adapter, and make the necessary changes there. – Linus Lindgren May 05 '23 at 08:04
  • can you please remove viewModel.getHunts().observe(this)? put that outside, and just set the list as a setter. in the adapter – Uriel Frankel May 08 '23 at 03:14

0 Answers0