Hello everyone, today’s topic is about how to drag an item on recycler view and drop that item on another position.
Firstly, we have to create a new project and add the dependencies on the app build. gradle file.
1 |
implementation 'androidx.recyclerview:recyclerview:1.2.0-alpha01' |
and also enable data binding on the app build.gradle file.
1 2 3 4 5 6 7 |
android { ------- ------- dataBinding{ enabled=true } } |
Now we can start working on the coding to add drag and drop functionality on recycler view.
- Create the layout having the recycler view: activity_language.xml
123456789101112131415161718<?xml version="1.0" encoding="utf-8"?><layout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"><androidx.appcompat.widget.LinearLayoutCompatandroid:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><androidx.recyclerview.widget.RecyclerViewandroid:id="@+id/language_rv"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@android:color/white"/></androidx.appcompat.widget.LinearLayoutCompat></layout> - For now let’s add the layout for an item let’s name it: item_language.xml
1234567891011121314151617181920212223242526272829303132333435363738394041<?xml version="1.0" encoding="utf-8"?><layout xmlns:tools="http://schemas.android.com/tools"xmlns:android="http://schemas.android.com/apk/res/android"><data><variablename="data"type="String" /></data><RelativeLayoutandroid:id="@+id/main_container"android:layout_width="match_parent"android:layout_height="wrap_content"android:background="@android:color/white"><TextViewandroid:id="@+id/language_label"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="@{data}"android:padding="@dimen/spacing_normal"android:textColor="@color/colorPrimaryDark"android:textSize="@dimen/text_size_big"android:textStyle="bold"tools:text="asidfnasfh"android:layout_toStartOf="@id/drag_iv"/><androidx.appcompat.widget.AppCompatImageViewandroid:id="@+id/drag_iv"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/swap"android:layout_margin="@dimen/spacing_normal"android:layout_alignParentEnd="true"android:layout_centerVertical="true"/></RelativeLayout></layout> - The code for the adapter class let’s name it: LanguageRvAdapter.java
1234567891011121314151617181920class LanguageRvAdapter(private val context: Context, var mLanguageList:ArrayList<String> ):RecyclerView.Adapter<LanguageRvAdapter.ViewHolder>(){override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {return ViewHolder(LayoutInflater.from(context).inflate(R.layout.item_language,parent,false))}override fun getItemCount(): Int {return mLanguageList.size}override fun onBindViewHolder(holder: ViewHolder, position: Int) {holder.mBinding?.data=mLanguageList[position]}class ViewHolder(itemView: View):RecyclerView.ViewHolder(itemView){val mBinding:ItemLanguageBinding?=DataBindingUtil.bind(itemView)}} - We are almost complete and now on the activity file, we will start to implement the code for recycler view, drag and drop, let’s name the activity file as LanguageActivity.kt.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112class LanguageActivity : AppCompatActivity() {lateinit var mBinding: ActivityLanguageBindinglateinit var languages: ArrayList<String>override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)mBinding = DataBindingUtil.setContentView(this, R.layout.activity_language)startInitialization()}private fun startInitialization() {/*initializing the languages Array List and adding data on it.*/setUpLanguageList()mBinding.languageRv.layoutManager =LinearLayoutManager(this, LinearLayoutManager.VERTICAL, false)mBinding.languageRv.adapter = LanguageRvAdapter(this, languages)/*Add Item touch helper to the recycler view*/val touchHelper = ItemTouchHelper(itemTouchCallback)touchHelper.attachToRecyclerView(mBinding.languageRv)}private fun setUpLanguageList() {languages = ArrayList()languages.add("java")languages.add("Kotlin")languages.add("swift")languages.add("c")languages.add("c++")languages.add("PHP")languages.add("Swift")languages.add("C# (C- Sharp)")languages.add(" Python")languages.add("JavaScript")}private var itemTouchCallback: ItemTouchHelper.Callback = object : ItemTouchHelper.Callback() {override fun getMovementFlags(recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder): Int {val dragFlags = ItemTouchHelper.UP or ItemTouchHelper.DOWNreturn makeMovementFlags(dragFlags, 0)}override fun onMove(recyclerView: RecyclerView,viewHolder: RecyclerView.ViewHolder,target: RecyclerView.ViewHolder): Boolean {onItemMoved(viewHolder.adapterPosition, target.adapterPosition)return true}override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {if (viewHolder is LanguageRvAdapter.ViewHolder) {val myViewHolder: LanguageRvAdapter.ViewHolder =viewHolderonItemSelected(myViewHolder)}}super.onSelectedChanged(viewHolder, actionState)}override fun clearView(recyclerView: RecyclerView, viewHolder: RecyclerView.ViewHolder) {super.clearView(recyclerView, viewHolder)if (viewHolder is LanguageRvAdapter.ViewHolder) {val myViewHolder: LanguageRvAdapter.ViewHolder =viewHolderonItemReleased(myViewHolder)}}override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {}override fun isLongPressDragEnabled(): Boolean {return true}}private fun onItemReleased(myViewHolder: LanguageRvAdapter.ViewHolder) {myViewHolder.mBinding?.mainContainer?.setBackgroundColor(Color.WHITE)}private fun onItemMoved(fromPosition: Int, toPosition: Int) {if (fromPosition < toPosition) {for (i in fromPosition until toPosition) {swap(languages, i, i + 1)}} else {for (i in fromPosition downTo toPosition + 1) {swap(languages, i, i - 1)}}mBinding.languageRv.adapter?.notifyItemMoved(fromPosition, toPosition)}fun onItemSelected(myViewHolder: LanguageRvAdapter.ViewHolder) {myViewHolder.mBinding?.mainContainer?.setBackgroundColor(Color.LTGRAY)}}
On this, we have created an object of ItemTouchHelper. Callback through which we will be able to implement the drag and drop feature, inside this, we have overridden multiple methods:- getMovementFlags -> We have to pass the directions of drag(Like ItemTouchHelper.UP or ItemTouchHelper.DOWN) and for swipe, we have passed the flag 0.
- onMove -> On this method the actual drag and drop functionality is provided.
- onSwipe ->We have to add the code for swiping but we are leaving it empty because we have already worked on the onMove method for swapping.
- onSelectedChanged -> When the particular selected item of recycler view is released the clearView method is invoked but for now when the item of recycler view is selected we are changing the background color of the item view.
- clearView -> When the particular selected item of recycler view is released the clearView method is invoked and but for now we are changing the background color of the item view.
- isLongPressDragEnabled -> This is returning true to enable the long press on the recycler view item for the drag and drop.
If you want to understand more about ItemTouchHelper then check this link: https://developer.android.com/reference/android/support/v7/widget/helper/ItemTouchHelper.html
. . . . . . . . .
I hope this blog was helpful to you.