Welcome to drag and drop RecyclerView item android example. In this tutorial, we’ll learn how to change the position of the recycler view items via drag and drop. For doing that, we will create a sample app that contains a recycler view with drag and drop functionality. Let’s get started.
Drag and Drop RecyclerView Item Demo App
1. Open android studio and create new project
Create a new android project with Kotlin and recycler view dependency inside app/build.gradle
implementation 'androidx.recyclerview:recyclerview:1.1.0'
2. Create RecyclerView Adapter
Now create a recycler view adapter named is DragDropRecyclerAdapter.
package com.dragdroprecyclerview import android.view.LayoutInflater import android.view.MotionEvent import android.view.View import android.view.ViewGroup import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.layout_recyclerview_item.view.* import java.util.* class DragDropRecyclerAdapter(private val startDragListener: OnStartDragListener) : RecyclerView.Adapter<DragDropRecyclerAdapter.ItemViewHolder>(), ItemMoveCallbackListener.Listener { private var users = emptyList<String>().toMutableList() fun setUsers(newUsers: List<String>) { users.addAll(newUsers) } override fun getItemCount(): Int { return users.size } override fun onBindViewHolder(holder: ItemViewHolder, position: Int) { val user = users[position] holder.bind(user) holder.itemView.imageView.setOnTouchListener { _, event -> if (event.action == MotionEvent.ACTION_DOWN) { this.startDragListener.onStartDrag(holder) } return@setOnTouchListener true } } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder { val itemView = LayoutInflater.from(parent.context) .inflate(R.layout.layout_recyclerview_item, parent, false) return ItemViewHolder(itemView) } class ItemViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { fun bind(text: String) { itemView.textView.text = text } } override fun onRowMoved(fromPosition: Int, toPosition: Int) { if (fromPosition < toPosition) { for (i in fromPosition until toPosition) { Collections.swap(users, i, i + 1) } } else { for (i in fromPosition downTo toPosition + 1) { Collections.swap(users, i, i - 1) } } notifyItemMoved(fromPosition, toPosition) } override fun onRowSelected(itemViewHolder: ItemViewHolder) { } override fun onRowClear(itemViewHolder: ItemViewHolder) { } }
3. Let’s create a layout file named is layout_recyclerview_item.xml and paste below code
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" android:padding="16dp" android:background="#F7EEEE" android:layout_margin="8dp"> <TextView android:id="@+id/textView" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:textSize="18sp" app:fontFamily="sans-serif-medium" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toStartOf="@+id/imageView" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" tools:text="Drag and Drop Recycler View example" /> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintTop_toTopOf="parent" app:srcCompat="@drawable/ic_scroll" /> </androidx.constraintlayout.widget.ConstraintLayout>
4. Write an ItemMoveCallback listener class which extends ItemTouchHelper.Callback
package com.dragdroprecyclerview import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView class ItemMoveCallbackListener(val adapter: DragDropRecyclerAdapter) : ItemTouchHelper.Callback() { override fun getMovementFlags( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder ): Int { val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWN return makeMovementFlags(dragFlags, 0) } override fun isItemViewSwipeEnabled(): Boolean { return false } override fun isLongPressDragEnabled(): Boolean { return false } override fun onMove( recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder ): Boolean { adapter.onRowMoved(viewHolder.adapterPosition, target.adapterPosition) return true } override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) { if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) { if (viewHolder is DragDropRecyclerAdapter.ItemViewHolder) { adapter.onRowSelected(viewHolder) } } super.onSelectedChanged(viewHolder, actionState) } override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) { super.clearView(recyclerView, viewHolder) if (viewHolder is DragDropRecyclerAdapter.ItemViewHolder) { adapter.onRowClear(viewHolder) } } override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) { } interface Listener { fun onRowMoved(fromPosition: Int, toPosition: Int) fun onRowSelected(itemViewHolder: DragDropRecyclerAdapter.ItemViewHolder) fun onRowClear(itemViewHolder: DragDropRecyclerAdapter.ItemViewHolder) } }
5. Open main activity layout file and paste below code
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context=".MainActivity"> <androidx.recyclerview.widget.RecyclerView android:id="@+id/recyclerView" android:layout_width="0dp" android:layout_height="0dp" android:layout_marginStart="8dp" android:layout_marginLeft="8dp" android:layout_marginTop="8dp" android:layout_marginEnd="8dp" android:layout_marginRight="8dp" android:layout_marginBottom="8dp" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> </androidx.constraintlayout.widget.ConstraintLayout>
6. Finally, Open main activity source file and add below code
package com.dragdroprecyclerview import android.os.Bundle import androidx.appcompat.app.AppCompatActivity import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.RecyclerView import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity(), OnStartDragListener { lateinit var adapter: DragDropRecyclerAdapter lateinit var touchHelper: ItemTouchHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) adapter = DragDropRecyclerAdapter(this) populateListItem() val callback: ItemTouchHelper.Callback = ItemMoveCallbackListener(adapter) touchHelper = ItemTouchHelper(callback) touchHelper.attachToRecyclerView(recyclerView) recyclerView.layoutManager = LinearLayoutManager(this) recyclerView.adapter = adapter } override fun onStartDrag(viewHolder: RecyclerView.ViewHolder) { touchHelper.startDrag(viewHolder) } private fun populateListItem() { val users = listOf( "Anuj", "Bhanu", "Chetan", "Devendra", "Esha", "Farmod", "Ganesh", "Hemant", "Ishaan", "Jack", "Kamal", "Lalit", "Mona" ) adapter.setUsers(users) } }
Conclusion
In this android example, We have learned the implementation Drag and drop RecyclerView item Android. I hope it’s helpful for you, then help me by sharing this post with all your friends.
Get Solution Code
Keep in touch
If you want to keep in touch and get an email when I write new blog posts, follow me on facebook or subscribe to us
Better way of debugging and logging your android application
6 Comments
interface OnStartDragListener {
fun onStartDrag(viewHolder: RecyclerView.ViewHolder)
}
Apologies for the noob question. Where do I put this?
interface OnStartDragListener {
fun onStartDrag(viewHolder: RecyclerView.ViewHolder)
}
OK I figured out that I needed to make a new listener class like this. However how do I initialize it?
you can use it in onCreate of your activity
The reference ‘this’ will do the trick of initializing the interface callback, since it is implemented in the Activity.
HI! thats a good example but it works?? I have’nt reference to “OnStartDragListener” . PLease help me
interface OnStartDragListener {
fun onStartDrag(viewHolder: RecyclerView.ViewHolder)
}