【问题标题】:The specified child already has a parent. You must call removeView() on the child's parent first. Still not fixed指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。还没有修好
【发布时间】:2020-12-28 12:43:20
【问题描述】:

我正在关注这个拖放示例:

https://www.tutlane.com/tutorial/android/android-drag-and-drop-with-examples

到目前为止一切都很好,除了声明的错误“指定的孩子已经有一个父母。您必须首先在孩子的父母上调用 removeView()。”在DragEvent.ACTION_DROPcontainer.addView(vw)。我已经使用了这里的解决方案:

The specified child already has a parent. You must call removeView() on the child's parent first (Android)

并在抛出错误的行之前添加

if (vw.parent != null) {
    val viewGroup = vw.parent as ViewGroup
    viewGroup.removeView(vw)
}

container.removeAllViews()

但这似乎并不能解决错误,这是我的完整代码:

private fun setupDragDropMechanic() {
    textView_test.tag = "DRAGGABLE TEXTVIEW"
    textView_test.setOnLongClickListener(this)

    layout1.setOnDragListener(this)
}

override fun onDrag(v: View?, event: DragEvent?): Boolean {
    // Defines a variable to store the action type for the incoming event
    when (event!!.action) {
        DragEvent.ACTION_DRAG_STARTED -> {
            // Determines if this View can accept the dragged data
            return event.clipDescription.hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)
        }
        DragEvent.ACTION_DRAG_ENTERED -> {
            v!!.background
                .setColorFilter(
                    resources.getColor(R.color.colorToolbar),
                    PorterDuff.Mode.SRC_IN
                )
            // force a redraw
            v.invalidate()
            return true
        }
        DragEvent.ACTION_DRAG_LOCATION ->
            // Ignored
            return true
        DragEvent.ACTION_DRAG_EXITED -> {
            v!!.background.clearColorFilter()
            v.invalidate()
            return true
        }
        DragEvent.ACTION_DROP -> {
            // Gets the item containing the dragged data
            val item = event.clipData.getItemAt(0)
            // Gets the text data from the item.
            val dragData = item.text.toString()
            Log.d("TAG", "data was dropped containing $dragData")

            v!!.background.clearColorFilter()
            v.invalidate()
            val vw = event.localState as View
            val owner = vw.parent as ViewGroup
            owner.removeView(vw) //remove the dragged view
            //caste the view into LinearLayout as our drag acceptable layout is LinearLayout
            val container = v as LinearLayout

            if (vw.parent != null) {
                val viewGroup = vw.parent as ViewGroup
                viewGroup.removeView(vw)
            }

            container.removeAllViews()
            container.addView(vw) //Add the dragged view
            vw.visibility = View.VISIBLE //finally set Visibility to VISIBLE
            // Returns true. DragEvent.getResult() will return true.

            // remove listener from view so user can't drop again
            v.setOnDragListener(null)
            // remove listener from dragged view
            vw.setOnLongClickListener(null)

            v.invalidate()

            return true
        }
        DragEvent.ACTION_DRAG_ENDED -> {
            if (event.result) {
                Log.d("TAG", "Drop handled successful")
            } else {
                Log.d("TAG", "Drop failed to handle")
            }

            return true
        }
        else -> Log.d("hh", "Unknown action type received by OnDragListener")
    }
    return false
}

override fun onLongClick(v: View?): Boolean {
    // Create a new ClipData.Item from the ImageView object's tag
    val item = ClipData.Item(v!!.tag as CharSequence)
    // Create a new ClipData using the tag as a label, the plain text MIME type, and
    // the already-created item. This will create a new ClipDescription object within the
    // ClipData, and set its MIME type entry to "text/plain"
    val mimeTypes = arrayOf(ClipDescription.MIMETYPE_TEXT_PLAIN)
    val data = ClipData(v.tag.toString(), mimeTypes, item)
    // Instantiates the drag shadow builder.
    val dragshadow = DragShadowBuilder(v)
    // Starts the drag
    v.startDrag(
        data // data to be dragged
        , dragshadow // drag shadow builder
        , v // local data about the drag and drop operation
        , 0 // flags (not currently used, set to 0)
    )
    return true
}

还有我的 XML 布局:

<!-- DRAG DROP -->
<TextView
    android:id="@+id/textView_test"
    android:layout_width="200dp"
    android:layout_height="50dp"
    android:gravity="center"
    android:background="@drawable/rounded_border"
    android:layout_below="@+id/linearLayout_button_hide_show_question"
    android:text="Das ist mein Text zum ziehen"/>


<LinearLayout
    android:id="@+id/layout1"
    android:layout_width="200dp"
    android:layout_height="50dp"
    android:orientation="vertical"
    android:background="#00ADEF"
    android:layout_marginBottom="50dp"
    android:layout_alignParentBottom="true"/>

【问题讨论】:

    标签: java android kotlin drag-and-drop


    【解决方案1】:

    我修正了错误。布局被包裹在一个RelativeLayout中,并且不知何故dragDrop无法处理这个布局。所以我把它从 RealtiveLayout 中移出,它就像一个魅力

    【讨论】:

      猜你喜欢
      • 2015-09-06
      • 2015-03-20
      • 1970-01-01
      • 1970-01-01
      • 2013-10-18
      • 2020-02-16
      相关资源
      最近更新 更多