Home > OS >  MERGE ITEMS in Recycler View when dragged & dropped on one another, in ANDROID?
MERGE ITEMS in Recycler View when dragged & dropped on one another, in ANDROID?

Time:12-05

Using ItemTouchHelper class we can DRAG, DROP, & SWIPE items in the recycler view; but how to just merge two items when dragged & dropped on one another?

Is it possible to do using ItemTouchHelper (or) is there any other API for that?

CodePudding user response:

You could override onMove() in your ItemTouchHelper, it is called when you drag item A over item B. It gets called with the parameters viewHolder: RecyclerView.ViewHolder and target: RecyclerView.ViewHolder where viewHolder is the viewHolder of item A, and target is item B.

Have some variable of type ViewHolder, that you set to target in onMove, to always have a reference to the item below item A.

override clearView() to detect when the item is dropped, update your model in the background, so itemA now is merged with target, then call notifyItemChanged(itemA.adapterPosition) and notifyItemRemoved(itemB.adapterPosition) to animate a "merge"

class MainActivity : AppCompatActivity() {

    companion object{
        val fruit = arrayListOf("apple", "pear", "orange", "banana", "grape", "pineapple")
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val recyclerView1 = findViewById<RecyclerView>(R.id.testRecycler)
        val layoutManager = LinearLayoutManager(this)
        recyclerView1.layoutManager = layoutManager

        val adapter = FruitAdapter()
        recyclerView1.adapter = adapter

        val itemTouchHelper = ItemTouchHelper(
            object : ItemTouchHelper.SimpleCallback(
                ItemTouchHelper.UP or ItemTouchHelper.DOWN,
                0
            ) {
                @SuppressLint("StaticFieldLeak")
                var target: RecyclerView.ViewHolder? = null
                @SuppressLint("StaticFieldLeak")
                var moving: RecyclerView.ViewHolder? = null
                override fun clearView(
                    recyclerView: RecyclerView,
                    viewHolder: RecyclerView.ViewHolder
                ) {
                    if(target!=null && moving != null){
                        val targetPos = target!!.adapterPosition
                        val sourcePos = moving!!.adapterPosition
                        fruit[targetPos]  = "\n\n"   fruit[sourcePos]
                        fruit.removeAt(sourcePos)
                        target = null
                        moving = null
                        adapter.notifyDataSetChanged()
                    }
                }

                override fun onMove(
                    recyclerView: RecyclerView,
                    viewHolder: RecyclerView.ViewHolder, target: RecyclerView.ViewHolder
                ): Boolean {
                    this.target = target
                    this.moving = viewHolder
                    return true
                }

                override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
                    TODO("Not yet implemented")
                }
            })

        itemTouchHelper.attachToRecyclerView(recyclerView1)
    }
}

class FruitAdapter: RecyclerView.Adapter<FruitAdapter.FruitViewHolder>() {

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): FruitViewHolder {
        val itemView = LayoutInflater.from(parent.context)
            .inflate(R.layout.item, parent, false)
        return FruitViewHolder(itemView)
    }
    override fun onBindViewHolder(holder: FruitViewHolder, position: Int) {
        holder.itemView.findViewById<TextView>(R.id.fruitNameTextView).text = MainActivity.fruit[position]
    }

    override fun getItemCount(): Int {
        return MainActivity.fruit.size
    }

    class FruitViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView){}
}

item.xml:

<?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"
    android:layout_width="match_parent"
    android:padding="20px"
    android:layout_margin="20px"
    android:background="@color/teal_200"
    android:layout_height="wrap_content">

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@ id/fruitNameTextView"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

activity_main.xml:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    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:layout_width="match_parent"
        android:id="@ id/testRecycler"
        android:layout_height="match_parent"/>

</androidx.constraintlayout.widget.ConstraintLayout>
  • Related