如何关闭自定义弹出窗口

时间:2021-06-13 15:33:09

标签: android drag-and-drop popupwindow dismiss

我遇到了弹出窗口和拖放问题。我想关闭弹出窗口并在将视图拖动到另一个视图时显示一个新窗口。我可以创建一个新的弹出窗口,但不能关闭旧的。我怎么解决这个问题?这总是会创建一个新的。

调用组件dismiss方法可以但是不能dismiss。

`
class SubstitutionPopUpComponent @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : PopupWindow(context, attrs, defStyleAttr) {
    val binding: ComponentPlayerSubstitutionPopupBinding = DataBindingUtil.inflate(
        LayoutInflater.from(context),
        R.layout.component_player_substitution_popup,
        null,
        false
    )

fun createPopup(
    view: View,
    playerInName: String,
    playerOutName: String,
): PopupWindow {
    binding.apply {
        this.playerInName = playerInName
        this.playerOutName = playerOutName
    }
    val x = view.getScreenLocation()[0]
    val y = view.getScreenLocation()[1]

    return PopupWindow(
        binding.root,
        ViewGroup.LayoutParams.WRAP_CONTENT,
        ViewGroup.LayoutParams.WRAP_CONTENT
    ).apply {
        isOutsideTouchable = true
        isFocusable = true
        elevation = 10f
        setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
        showAtLocation(view, Gravity.NO_GRAVITY, x + view.width, y)
    }
}

fun dismissPopup() {
    dismiss()
}

}`

internal class MyDragListener(ctx: Context, popUpComponent: SubstitutionPopUpComponent?) :
        OnDragListener {
        val context = ctx
        val substitutionPopUpComponent = popUpComponent
        override fun onDrag(target: View, event: DragEvent): Boolean {
            when (event.action) {
                DragEvent.ACTION_DROP -> {
                    if (substitutionPopUpComponent.isNotNull()) {
                        substitutionPopUpComponent?.dismissPopup()
                    }

                    val dragged = event.localState as View
                    val oldPlayer = dragged.parent as ViewGroup
                    val newPlayer = target.parent as ViewGroup

                    when {
                        (oldPlayer as SquadPlayerComponent).binding.player != null -> {
                            when ((newPlayer as SquadPlayerComponent).playerPosition) {
                                oldPlayer.playerPosition -> {
                                    if (oldPlayer.binding.player != null && newPlayer.binding.player != null) {
                                        Utils.swapPlayers(
                                            oldPlayer.binding.player!!,
                                            newPlayer.binding.player!!,
                                            oldPlayer.isSubPlayer,
                                            newPlayer.isSubPlayer,
                                            newPlayer.playerPosition.toString()
                                        )
                                    }
                                }
                            }
                        }
                    }
                }
                DragEvent.ACTION_DRAG_ENTERED -> {
                    val dragged = event.localState as View
                    val oldPlayer = dragged.parent as ViewGroup
                    val newPlayer = target.parent as ViewGroup

                    substitutionPopUpComponent?.apply {
                        createPopup(oldPlayer,
                            (newPlayer as SquadPlayerComponent).binding.player?.name.toString(),
                            (oldPlayer as SquadPlayerComponent).binding.player?.name.toString()
                        )
                    }
                }

                DragEvent.ACTION_DRAG_EXITED -> {
                    if (substitutionPopUpComponent.isNotNull()) {
                        substitutionPopUpComponent?.dismissPopup()
                    }
                }
            }
            return true
        }
    }

1 个答案:

答案 0 :(得分:0)

看起来自 android api 级别 24 以来,视图具有方法 updateDragShadow,它更新正在进行的拖放操作的拖动阴影。也就是说,您可以将 DragShadowBuilder 的新实例传递给您的 DragListener 中的 target.updateDragShadow(emptyDragShadowBuilder),该实例将是透明的或不绘制任何内容,您就可以获得所需的内容。

我不确定,但我认为你可以在没有 updateDragShadow 的情况下做同样的事情: 当您调用 startDragAndDrop 方法时,您可以使用视图对象传递 DragShadowBuilder 的实例。考虑实施 DragShadowBuilder.onDrawShadow:

public void onDrawShadow(Canvas canvas) {
            final View view = mView.get();
            if (view != null) {
                view.draw(canvas);
            } else {
                Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view");
            }
        }

看起来您可以更改传递给 DragShadowBuilder 的视图并在此视图上调用无效。或者您可以扩展将缓存画布的 DragShadowBuilder,然后在更改视图后调用 onDrawShadow() 将使用缓存的画布:

public void onDrawShadow(Canvas canvas) {
            mCanvas = canvas;
            onDrawShadow();
        }

public void onDrawShadow() {
            final View view = mView.get();
            if (view != null && mCanvas != null) {
                view.draw(mCanvas);
            } else {
                Log.e(View.VIEW_LOG_TAG, "Asked to draw drag shadow but no view");
            }
        }