在现代应用程序中,用户交互性是提供丰富用户体验的关键因素。RecyclerView
作为Android中处理列表和网格布局的强大组件,支持多种交互,包括拖放排序。本文指导您如何在RecyclerView
中实现拖放功能,使用户能够通过长按和拖动来重新排序列表项,用Kotlin实现
为了为RecyclerView
添加长按拖放功能,我们将通过自定义ItemTouchHelper.Callback
来精确控制拖动行为,涉及重写onMove
方法和getMovementFlags
方法
首先,为列表项编写XML布局文件,如 item_type_one.xml
:
//item_type_one.xml,依此类推...
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="640px"
android:layout_height="200px"
android:background="@color/black">
</LinearLayout>
视图布局结构如图下
创建 MyAdapter
类,继承自 RecyclerView.Adapter
实现 onCreateViewHolder
和 onBindViewHolder
方法:
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.nim.recyclerviewtechdemo.Item
import com.nim.recyclerviewtechdemo.R
import java.util.Collections
/**
* @author Nimyears
*/
class MyAdapter(items: List<Item?>) : RecyclerView.Adapter<RecyclerView.ViewHolder>() {
private val items: List<Item?> = items
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
val view: View
when (viewType) {
0 -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_type_one, parent, false)
return TypeOneViewHolder(view)
}
1 -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_type_two, parent, false)
return TypeTwoViewHolder(view)
}
2 -> {
view = LayoutInflater.from(parent.context)
.inflate(R.layout.item_type_three, parent, false)
return TypeThreeViewHolder(view)
}
....
else -> throw IllegalArgumentException("无效视图类型")
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
//...
}
override fun getItemCount(): Int {
return items.size
}
override fun getItemViewType(position: Int): Int {
return items[position]?.type ?: 0
}
fun moveItem(fromPosition: Int, toPosition: Int) {
if (fromPosition < toPosition) {
for (i in fromPosition until toPosition) {
Collections.swap(items, i, i + 1)
}
} else {
for (i in fromPosition downTo toPosition + 1) {
Collections.swap(items, i, i - 1)
}
}
notifyItemMoved(fromPosition, toPosition)
}
internal class TypeOneViewHolder(itemView: View?) : RecyclerView.ViewHolder(
itemView!!
)
internal class TypeTwoViewHolder(itemView: View?) : RecyclerView.ViewHolder(
itemView!!
)
internal class TypeThreeViewHolder(itemView: View?) : RecyclerView.ViewHolder(
itemView!!
)
....
}
RecyclerView
和适配器在 MainActivity
中配置 RecyclerView
和适配器:
/**
* @author Nimyears
*/
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val items: MutableList<Item?> = ArrayList()
for (i in 0..7) {
items.add(Item(i))
}
val recyclerView = findViewById<RecyclerView>(R.id.recyclerView)
val layoutManager = GridLayoutManager(this, 2, GridLayoutManager.HORIZONTAL, false)
recyclerView.layoutManager = layoutManager
val adapter = MyAdapter(items)
recyclerView.adapter = adapter
}
}
moveItem
函数在适配器中实现 moveItem
函数,用于交换数据集中的元素位置,通知 RecyclerView
更新:
override fun getItemCount(): Int {
return items.size
}
override fun getItemViewType(position: Int): Int {
return items[position]?.type ?: 0
}
//TODO 这段代码块是重点
fun moveItem(fromPosition: Int, toPosition: Int) {
if (fromPosition < toPosition) {
for (i in fromPosition until toPosition) {
Collections.swap(items, i, i + 1)
}
} else {
for (i in fromPosition downTo toPosition + 1) {
Collections.swap(items, i, i - 1)
}
}
notifyItemMoved(fromPosition, toPosition)
}
ItemTouchHelper
实例设置回调创建 ItemTouchHelper
实例设置回调启用拖放功能:
val itemTouchHelper = ItemTouchHelper(object : ItemTouchHelper.Callback() {
override fun getMovementFlags(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder
): Int {
return makeMovementFlags(
ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT,
0
)
}
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
val fromPosition = viewHolder.adapterPosition
val toPosition = target.adapterPosition
adapter.moveItem(fromPosition, toPosition)
return true
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
//不需要编写
}
})
itemTouchHelper.attachToRecyclerView(recyclerView)
}
通过上述步骤,可以轻松地在Android应用中的RecyclerView
实现拖放排序功能。
谢谢大家的阅读,如果您觉得这篇文章对您有所帮助,请给我点赞和支持,非常感谢: )
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。