DSAppTeam / RecyclerViewDrag

:white_check_mark: 基于RecyclerView实现的可拖拽/合并交互,比如顺序改变/合并成文件夹等

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

控件叠放问题

protectedMan opened this issue · comments

commented

基于demo做了初步改动,recycler_view_folder叠放在了recycler_view之上,当recycler_view_folder的item拖拽时,还没有移出recycler_view_folder区域,松开手就已进入recycler_view列表了.
我想实现在recycler_view_folder区域的拖拽不不会进入recycler_view中.
问题演示见视频

QQ20230414-113315-HD.mp4

image
最终想实现的效果如下图(和手机桌面相似)
image

/**
 * 是否可以交换位置
 */
fun swapPosition(fromPosition: Int, toPosition: Int): Boolean 

尝试重写这个方法,当你拖动的item移动出你文件夹区域时才可以返回ture,否则返回false

commented

我试了下,把几个swapPosition属性都设为了false
如果我从recycler_view_folder的item拖动到recycler_view上方还会swap(也还是视频上的效果,问题依旧)

可以把你写的demo 发个 pull request给我吗,我也想看看

image
demo中有个比较类似你这个的交互,在合适的时机把拖动的item在目标RecyclerView中add / remove

commented

PR不太会弄, 项目打包发你看看,其实就像实现的就是现在手机都有的那种桌面图标管理效果,支持拖到文件夹,或者从文件夹拖出
RecyclerViewDrag.zip

ok,晚些我试试,你可以先研究一下

    /**
     * 根据拖拽位置,显示、隐藏预览项
     * @param viewHolder 被拖拽的ViewHolder
     * @param left viewHolder相对当前window的left
     * @param top  viewHolder相对当前window的top
     * @param activity 是否被拖动,释放拖动时 activity == false
     */
    private fun notifyPreviewViewHolder(viewHolder: RecyclerView.ViewHolder?, left: Float, top: Float, activity: Boolean) {
        if (activity) {
            val targetView = viewHolder?.itemView
            val parentView = viewHolder?.itemView?.parent as? View
            if (targetView != null && parentView != null) {
                targetView.getGlobalVisibleRect(targetRect)
                parentView.getGlobalVisibleRect(parentRect)
                // 判断拖动的控件和父控件位置是否相交
                if (Rect.intersects(parentRect, targetRect)) {
                    updatePreviewPosition(-1, viewHolder) //文件夹列表内
                } else {
                    val y = top - location[1]
                    val position = findBestPosition(y.toInt(), recyclerView)
                    updatePreviewPosition(position, viewHolder)
                }
            } else {
                updatePreviewPosition(-1, viewHolder) //文件夹列表内
            }
        } else {
            replacePreview(viewHolder)
        }
    }

用这段逻辑,具体细节你慢慢调整

commented

还有个问题, recycler_view的拖拽开始和结束时间可以监听到, 我如何监听到 recycler_view_folder的拖拽和结束事件呢?

commented

还有个问题, recycler_view的拖拽开始和结束时间可以监听到, 我如何监听到 recycler_view_folder的拖拽和结束事件呢?

recycler_view_folder没有暴露相关事件

/**
 * 根据拖拽位置,显示、隐藏预览项
 * @param viewHolder 被拖拽的ViewHolder
 * @param left viewHolder相对当前window的left
 * @param top  viewHolder相对当前window的top
 * @param activity 是否被拖动,释放拖动时 activity == false
 */

上面那个方法中的 activity 参数就是标识当前拖动状态是否激活,你想要的这个事件官方源码已经提供了