最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

天天观察:scrollView 嵌套 recyclerview 时 BaseQuickAdapter 九宫格图片拖拽到底部删除

来源:博客园

九宫格图片布局,长按直接拖拽图片,长按时显示底部删除布局,拖拽到删除布局处松手可删除布局,最后添加按钮不可拖拽,基于 BaseQuickAdapter 基础上实现

BaseQuickAdapter 确实很好用,简化我们的实现代码,它本身也集成了一套拖拽实现,不过目前无法完美的满足上面的需求,需要做一些修改


(资料图片仅供参考)

1、首先自定义好九宫格布局,末尾是一个 + 号,这个加号无法拖拽,这里 + 号最好是用图片,更方便

2、在 adapter 中重写addDraggableModule方法,这里我直接自定义了自己的 DraggableModule ,因为我需要替换默认的监听事件,达到我自己的目的

核心逻辑就集中在 PhotoDraggableModule 中,否则自带的拖拽没发监听拖拽的距离,不好计算是否拖拽到了底部

源码中在 module 初始化的时候就已经把监听初始化了,所以在不替换的情况下,很难达到自己的需求

其实就是 DragAndSwipeCallback ,自己定义有点麻烦,还不如不用这套拖拽封装了,所以为了简化,只能继续用它,在它的基础上计算自己的拖拽距离就行了

直接在 module 中的 init 方法里 重新创建监听,去替换原有的 callback,这样就方便自己获取数据操作了

init {        itemTouchHelperCallback = object : DragAndSwipeCallback(this) {            override fun onChildDraw(                c: Canvas,                recyclerView: RecyclerView,                viewHolder: RecyclerView.ViewHolder,                dX: Float,                dY: Float,                actionState: Int,                isCurrentlyActive: Boolean            ) {                super.onChildDraw(                    c,                    recyclerView,                    viewHolder,                    dX,                    dY,                    actionState,                    isCurrentlyActive                )                if (callBack == null) return                if (isCurrentlyActive) {                    viewHolder.itemView.visibility = View.VISIBLE                    if (dY.toInt() == 0) {                        isDel = false                        callBack?.touchStart()                    } else if (dY > 0) {                        //拖到指定区域                        val bottom = (recyclerView.parent.parent as View).bottom + dY                        val bottomY =                            bottom - (recyclerView.bottom - viewHolder.itemView.bottom) - (scrollView?.scrollY                                ?: 0)                        //是否在删除区域                        isDel = bottomY >= bottomDelTopY                        callBack?.touchMove(isDel)                    }                } else {                    val delPosition = if (isDel) viewHolder.layoutPosition else null                    //松开先隐藏,预防松开后item回到列表在执行删除动画                    viewHolder.itemView.visibility = if (isDel) View.INVISIBLE else View.VISIBLE                    callBack?.touchUp(delPosition)                    isDel = false                }            }            @SuppressLint("NotifyDataSetChanged")            override fun clearView(                recyclerView: RecyclerView,                viewHolder: RecyclerView.ViewHolder            ) {                super.clearView(recyclerView, viewHolder)                viewHolder.itemView.visibility = View.VISIBLE                //等待布局操作结束执行刷新,避免下方异常                //Cannot call this method while RecyclerView is computing a layout or scroll                viewHolder.itemView.post {                    baseQuickAdapter.notifyDataSetChanged()                }            }        }        itemTouchHelper = ItemTouchHelper(itemTouchHelperCallback)    }

3、计算拖拽距离

如果没有被 scrollView 嵌套,直接通过拖拽的距离就能判断是否到底部了,但是一般情况下都需要你可滑动,就会需要嵌套一层 scrollVIew

根据上面代码看出,其实就是需要获取 scrollView 的滚动距离,从中得出你拖拽的距离是否到底部了,这里用 isDel 来控制执行次数,否则会重复调用多次

4、最后在回调监听中处理拖拽的动画和删除操作

关键词: 的情况下 一般情况下