Перетаскивание Android в том же представлении приводит к сообщению о результате перетаскивания: false

Я пытаюсь сделать повторный заказ GridLayout с перетаскиванием.

В основном, когда я что-то тащу в GridLayout, он должен изменить порядок GridLayout на основе перетаскивания.

у меня есть это GridLayout который имеет 6 FrameLayout внутри.

       <GridLayout
    android:id="@+id/myGridLayout"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:columnCount="3">

    <FrameLayout
        android:background="@android:color/holo_blue_dark"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_columnWeight="1">
    </FrameLayout>

    <FrameLayout
        android:background="@android:color/black"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_columnWeight="1">
    </FrameLayout>

    <FrameLayout
        android:background="@android:color/darker_gray"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_columnWeight="1">
    </FrameLayout>

    <FrameLayout
        android:background="@android:color/holo_green_dark"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_columnWeight="1">
    </FrameLayout>

    <FrameLayout
        android:background="@android:color/holo_purple"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_columnWeight="1">
    </FrameLayout>

    <FrameLayout
        android:background="@android:color/holo_red_dark"
        android:layout_width="0dp"
        android:layout_height="100dp"
        android:layout_columnWeight="1">
    </FrameLayout>

</GridLayout>

Так выглядит на скриншоте ниже

Я зарегистрировал все FrameLayouts в GridLayout для LongClickListner и DragListener согласно приведенным ниже кодам

           for (i in 0 until myGridLayout.childCount) {
        val childView = myGridLayout.getChildAt(i)

        childView.setOnLongClickListener {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                it.visibility = View.INVISIBLE
                it.startDragAndDrop(null, CustomDragShadowBuilder(it, lastTouch), it, 0)
            } else it.startDrag(null, CustomDragShadowBuilder(it, lastTouch), it, 0)
            true
        }


        childView.setOnDragListener { v, event ->
            when (event.action) {
                DragEvent.ACTION_DRAG_STARTED -> true
                DragEvent.ACTION_DRAG_ENTERED -> {
                        val draggingView = event.localState as View
                        val dragEnteredIndex = myGridLayout.indexOfChild(v)
                        val draggingViewIndex = myGridLayout.indexOfChild(draggingView)
                        myGridLayout.removeViewAt(draggingViewIndex)
                        myGridLayout.addView(draggingView, dragEnteredIndex)
                        true
                }
                DragEvent.ACTION_DRAG_LOCATION -> true
                DragEvent.ACTION_DRAG_EXITED -> true
                DragEvent.ACTION_DROP -> true
                DragEvent.ACTION_DRAG_ENDED -> {
                    val draggingView = event.localState as View
                    draggingView.post { run { draggingView.visibility = View.VISIBLE } }
                    true
                }
                else -> false
            }
        }
    }

Итак, когда вы перетаскиваете красный FrameLayoutперейти к серому FrameLayout, то DragEvent.ACTION_DRAG_ENTEREDназывается. Затем я просто удаляю красный FrameLayoutи добавьте его в индекс серого FrameLayout где DragShadow закончился, так что я могу изменить порядок GridLayoutв настоящее время. Итак, когда я двигаюсь FrameLayout в GridLayout, У меня получилось что-то вроде этого, чего я и ожидал.

Но, как видите, когда я отпускаю тягу, красный FrameLayout, или же DragShadow возвращается в исходное положение, и консоль говорит I/ViewRootImpl[MainActivity]: Reporting drop result: false. Наконец, DragEvent.ACTION_DRAG_ENDED называется и сделать красный FrameLayout видимый.

Итак, вот вопросы,

  1. почему сопротивление не работает? Это потому, что я отпускаю сопротивление над тем же FrameLayout, пожалуйста, какой красный?

  2. Есть ли способ предотвратить DragShadowвернуться в исходное положение? Я просто хочу, чтобы когда я отпускал тягу, я просто хочу FrameLayout появиться на новом месте, не возвращаясь в исходное положение.

Заранее спасибо, ребята.

1 ответ

Решение

Для тех, у кого такие же проблемы, я решил эту проблему, используя recyclerview с ItemTouchHelper, у которого есть функции перетаскивания. Вам не нужно вводить собственные коды.

Другие вопросы по тегам