在 ANDROID 中相互拖放时在 Recyclerview 中合并项目?
MERGE ITEMS in Recycler View when dragged & dropped on one another, in ANDROID?
使用 ItemTouchHelper class 我们可以在回收站视图中拖放、滑动项目;但是如何在相互拖放时合并两个项目?
是否可以使用 ItemTouchHelper(或)是否还有其他 API?
您可以覆盖 ItemTouchHelper
中的 onMove()
,当您将项目 A 拖到项目 B 上时调用它。它使用参数 viewHolder: RecyclerView.ViewHolder
和 target: RecyclerView.ViewHolder
调用其中 viewHolder
是项目 A 的 viewHolder,target
是项目 B。
有一些您在 onMove 中设置为目标的 ViewHolder 类型的变量,以始终引用项目 A 下的项目。
重写 clearView()
以检测物品何时掉落,在后台更新您的模型,因此 itemA 现在与目标合并,然后调用 notifyItemChanged(itemA.adapterPosition)
和 notifyItemRemoved(itemB.adapterPosition)
为 a 设置动画“合并”
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>
使用 ItemTouchHelper class 我们可以在回收站视图中拖放、滑动项目;但是如何在相互拖放时合并两个项目?
是否可以使用 ItemTouchHelper(或)是否还有其他 API?
您可以覆盖 ItemTouchHelper
中的 onMove()
,当您将项目 A 拖到项目 B 上时调用它。它使用参数 viewHolder: RecyclerView.ViewHolder
和 target: RecyclerView.ViewHolder
调用其中 viewHolder
是项目 A 的 viewHolder,target
是项目 B。
有一些您在 onMove 中设置为目标的 ViewHolder 类型的变量,以始终引用项目 A 下的项目。
重写 clearView()
以检测物品何时掉落,在后台更新您的模型,因此 itemA 现在与目标合并,然后调用 notifyItemChanged(itemA.adapterPosition)
和 notifyItemRemoved(itemB.adapterPosition)
为 a 设置动画“合并”
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>