【问题标题】:How to dismiss custom popup window如何关闭自定义弹出窗口
【发布时间】:2021-08-29 18:03:39
【问题描述】:

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

调用组件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
        }
    }

【问题讨论】:

  • 你解决问题了吗?
  • 是的@ArtemViter 我已将draglistener 更改为此并解决了问题。内部类 MyDragListener(private var substitutionPopUp: PopupWindow?) : OnDragListener {

标签: android drag-and-drop popupwindow dismiss


【解决方案1】:

看起来从 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 的视图并在此视图上调用 invalidate。或者您可以扩展将缓存画布的 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");
            }
        }

【讨论】:

    猜你喜欢
    • 2018-04-03
    • 2014-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-30
    相关资源
    最近更新 更多