【问题标题】:MERGE ITEMS in Recycler View when dragged & dropped on one another, in ANDROID?在ANDROID中相互拖放时合并Recyclerview中的项目?
【发布时间】:2022-01-10 12:51:03
【问题描述】:

使用 ItemTouchHelper 类,我们可以在回收站视图中拖放和滑动项目;但是如何在彼此拖放时合并两个项目?

是否可以使用 ItemTouchHelper(或)是否有任何其他 API 可以做到这一点?

【问题讨论】:

    标签: android android-recyclerview merge drag-and-drop itemtouchhelper


    【解决方案1】:

    您可以在 ItemTouchHelper 中覆盖 onMove(),当您将项目 A 拖到项目 B 上时会调用它。使用参数 viewHolder: RecyclerView.ViewHoldertarget: RecyclerView.ViewHolder 调用它,其中 viewHolder 是项目 A 的 viewHolder , 而target 是 B 项。

    有一些 ViewHolder 类型的变量,您在 onMove 中设置为目标,以始终引用项目 A 下方的项目。

    覆盖 clearView() 以检测项目何时被丢弃,在后台更新您的模型,因此 itemA 现在与目标合并,然后调用 notifyItemChanged(itemA.adapterPosition)notifyItemRemoved(itemB.adapterPosition) 为“合并”设置动画

    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>
    

    【讨论】:

    • 非常感谢,我会在实施后确认答案,但是在任何博客或文章中是否有任何示例?
    • 我编辑了我的答案,包括一个最小工作示例的代码,这可以让你拖放合并项目,但是它仍然需要大量的抛光,但它应该可以帮助你朝着正确的方向前进
    • 非常感谢您的帮助,我能够了解这项工作的技术背景。但是,是的,我们必须做更多的工作才能使合并成功。无论如何,tq这么多!
    猜你喜欢
    • 1970-01-01
    • 2015-07-06
    • 2017-06-23
    • 2018-07-26
    • 2020-10-13
    • 2014-07-11
    • 2020-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多