前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >AndroidApp和车机开发:RecyclerView实现触摸和拖放的功能

AndroidApp和车机开发:RecyclerView实现触摸和拖放的功能

原创
作者头像
Nimyears
修改2024-07-20 16:37:13
2470
修改2024-07-20 16:37:13

引言

在现代应用程序中,用户交互性是提供丰富用户体验的关键因素。RecyclerView作为Android中处理列表和网格布局的强大组件,支持多种交互,包括拖放排序。本文指导您如何在RecyclerView中实现拖放功能,使用户能够通过长按和拖动来重新排序列表项,用Kotlin实现

长按和拖放操作

为了为RecyclerView添加长按拖放功能,我们将通过自定义ItemTouchHelper.Callback来精确控制拖动行为,涉及重写onMove方法和getMovementFlags方法

拖动排序逻辑

  • onMove:此方法在拖动操作期间被调用,用于交换列表项的位置,并更新适配器的数据源。
  • getMovementFlags:在此方法中,我们将定义列表项可拖动的方向。

实现步骤

第一步:编写XML布局文件

首先,为列表项编写XML布局文件,如 item_type_one.xml

代码语言: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 实现 onCreateViewHolderonBindViewHolder 方法:

代码语言:java
复制
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 和适配器:

代码语言:java
复制
/**
 * @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 更新:

  • 比较源位置和目标位置。
  • 使用Collections.swap交换元素在列表中的位置。
  • 调用notifyItemMoved通知RecyclerView元素已移动。
代码语言:java
复制
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 实例设置回调启用拖放功能:

代码语言:javascript
复制
  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)
}

第六步:展示实现效果图

demo-1
demo-1
demo-2
demo-2
demo-3
demo-3

第七步:实战应用

UI-1
UI-1
UI-2
UI-2

注意事项

  • 测试长按和拖放功能以确保它们符合预期的用户体验。
  • 考在拖动操作期间提供视觉反馈,以增强交互性。

结语

通过上述步骤,可以轻松地在Android应用中的RecyclerView实现拖放排序功能。

谢谢大家的阅读,如果您觉得这篇文章对您有所帮助,请给我点赞和支持,非常感谢: )

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
  • 长按和拖放操作
    • 拖动排序逻辑
      • 实现步骤
        • 第一步:编写XML布局文件
          • 第二步:创建视图适配器
            • 第三步:配置 RecyclerView 和适配器
              • 第四步:实现 moveItem 函数
                • 第五步:创建 ItemTouchHelper 实例设置回调
                  • 第六步:展示实现效果图
                    • 第七步:实战应用
                    • 注意事项
                    • 结语
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档