小工具知识网

当前位置: 首页 > 行业知识 > 【Android】RecyclerView拖动排序和侧滑删除功能实现

行业知识

【Android】RecyclerView拖动排序和侧滑删除功能实现

2026-11-05 17:25:52 来源:互联网转载

目录

  • 简介
  • 一、ItemTouchHandler 拖动排序和侧滑删除
  • 二、SwipeDelMenuLayout 侧滑删除
  • 总结

    简介

    ItemTouchHandler 是 Google 提供的一个工具类,主要针对 RecyclerView 的上下左右拖动事件进行处理,可以同时实现拖动排序和侧滑删除功能。涉及一些事件分发的知识,感兴趣可以去分析源码。

    第三方SwipeDelMenuLayout,毫无耦合性,一个Item根布局搞定 item侧滑删除菜单。不依赖任何父布局,不是针对 RecyclerView、ListView,而是任意的 ViewGroup 里的 childView 都可以使用侧滑删除。


    一、ItemTouchHandler 拖动排序和侧滑删除

    效果展示:

    1. 先创建一个回调类:ItemTouchHelperCallBack
    • context:上下文
    • listData:列表数据
    • adapter:对应适配器
    • isDrag:是否可以拖拽
    • isSwipe:是否可以侧滑
      class ItemTouchHelperCallBack  (val context: Context,val listData:List,val adapter:BaseQuickAdapter,val isDrag:Boolean=true,val isSwipe:Boolean=true): ItemTouchHelper.Callback()
      1. 实现方法(这些方法也可以设置接口在外部去实现)
      • getMovementFlags:一个是dragFlags,表示拖动效果支持的方向,另一个是swipeFlags,表示侧滑效果支持的方向
        override fun getMovementFlags(        recyclerView: RecyclerView,        viewHolder: RecyclerView.ViewHolder    ): Int {        var dragFlag = 0        if (recyclerView.layoutManager is GridLayoutManager) {            dragFlag =                ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT        } else if (recyclerView.layoutManager is LinearLayoutManager) {            dragFlag = ItemTouchHelper.UP or ItemTouchHelper.DOWN        }        return makeMovementFlags(dragFlag, 0)    }
        • onMove:当拖动开始时会回调此方法,通常将拖动的item与其他item交换位置,更新数据源
          override fun onMove(        recyclerView: RecyclerView,        viewHolder: RecyclerView.ViewHolder,        target: RecyclerView.ViewHolder    ): Boolean {        //absoluteAdapterPosition和layoutPosition相差不大:        //  layoutPosition相对于实际展示的布局:使用场景一般在notifyItemInserted之后, Layout不能马上获取到新的position, 布局还没更新时        //  absoluteAdapterPosition相对于数据        val fromPosition = viewHolder.absoluteAdapterPosition        //拿到当前拖拽到的item的viewHolder        val toPosition = target.absoluteAdapterPosition        if (fromPosition  
          • onSwiped(可自行实现):当侧滑开始时调用,从数据源里面移除相应的数据
          • onSelectedChanged :长按选中Item的时候开始调用,设置震动效果
            override fun onSelectedChanged(viewHolder: RecyclerView.ViewHolder?, actionState: Int) {        if (actionState != ItemTouchHelper.ACTION_STATE_IDLE) {            //获取系统震动服务 震动70毫秒            val vib = context.getSystemService(AppCompatActivity.VIBRATOR_SERVICE) as Vibrator            vib.vibrate(50)        }        super.onSelectedChanged(viewHolder, actionState)    }
            • clearView:手指松开的时候调用,刷新数据
              override fun clearView(        recyclerView: RecyclerView,        viewHolder: RecyclerView.ViewHolder    ) {        super.clearView(recyclerView, viewHolder)        Handler().post(Runnable {            adapter.notifyDataSetChanged(); //完成拖动后刷新适配器,这样拖动后删除就不会错乱        })    }
              • isLongPressDragEnabled、isItemViewSwipeEnabled
                /**     * 是否支持长按拖拽,默认为true,表示支持长按拖拽     * 对应长按移动位置功能     * 也可以返回false,手动调用startDrag()方法启动拖拽     */    override fun isLongPressDragEnabled(): Boolean {        return isDrag    }    /**     * 是否支持任意位置触摸事件发生时启用滑动操作,默认为true,表示支持滑动     * 对应滑动删除功能     * 也可以返回false,手动调用startSwipe()方法启动滑动     */    override fun isItemViewSwipeEnabled(): Boolean {        return isSwipe    }

                全部代码:

                class ItemTouchHelperCallBack  (val context: Context,val listData:List,val adapter:BaseQuickAdapter,val isDrag:Boolean=true,val isSwipe:Boolean=true): ItemTouchHelper.Callback() {    //一个是dragFlags,表示拖动效果支持的方向,另一个是swipeFlags,表示侧滑效果支持的方向    override fun getMovementFlags(        recyclerView: RecyclerView,        viewHolder: RecyclerView.ViewHolder    ): Int {        var dragFlag = 0        if (recyclerView.layoutManager is GridLayoutManager) {            dragFlag =                ItemTouchHelper.UP or ItemTouchHelper.DOWN or ItemTouchHelper.LEFT or ItemTouchHelper.RIGHT        } else if (recyclerView.layoutManager is LinearLayoutManager) {            dragFlag = ItemTouchHelper.UP or ItemTouchHelper.DOWN        }        return makeMovementFlags(dragFlag, 0)    }    //当拖动效果已经产生了,会回调此方法,通常会更新数据源    override fun onMove(        recyclerView: RecyclerView,        viewHolder: RecyclerView.ViewHolder,        target: RecyclerView.ViewHolder    ): Boolean {        //absoluteAdapterPosition和layoutPosition相差不大:        //  layoutPosition相对于实际展示的布局:使用场景一般在notifyItemInserted之后, Layout不能马上获取到新的position, 布局还没更新时        //  absoluteAdapterPosition相对于数据        val fromPosition = viewHolder.absoluteAdapterPosition        //拿到当前拖拽到的item的viewHolder        val toPosition = target.absoluteAdapterPosition        if (fromPosition  
                1. 使用

                先设置isDrag为false,指定某个控件再去启动拖动

                private val itemTouchHelper by lazy {        //数据listData会改变        ItemTouchHelper(            ItemTouchHelperCallBack(                context = this,                listData = itemData,                adapter = itemAdapter,                isDrag = false            )        )    }//与recyclerView控件绑定itemTouchHelper.attachToRecyclerView(rv_add_item)//指定item里面的某个控件长按才能拖动adapter.setLongClickInterface(object :SetShowTabAdapter.LongClickInterface{            override fun onDrag(holder: BaseViewHolder) {                itemTouchHelper.startDrag(holder)            }        })

                二、SwipeDelMenuLayout 侧滑删除

                效果展示:

                1. 导入依赖
                 implementation 'com.github.mcxtzhang:SwipeDelMenuLayout:V1.3.0'
                1. xml设置

                在适配器的item布局中,给需要滑动删除那个控件外层添加一个 SwipeMenuLayout 标签包裹住控件和一个删除按钮,让控件宽度铺满屏幕

                                                                                                        
                1. 使用

                  使用非常简单,只需要在适配器配置相应的点击事件即可

                holder.getView(R.id.btn_delete).setOnClickListener {            if(holder.absoluteAdapterPosition in 0 until itemCount){                list.removeAt(holder.absoluteAdapterPosition) //移除数据                notifyItemRemoved(holder.absoluteAdapterPosition) //刷新adapter            }        }

                总结

                实现这两个功能有很多方法,都是比较简单的。


                很长时间没更新了,之前去备考了,希望能有个好结果吧

上一篇:西子服务器怎么查看故障?

下一篇:Web 服务器的搭建