我遇到了弹出窗口和拖放问题。我想关闭弹出窗口并在将视图拖动到另一个视图时显示一个新窗口。我可以创建一个新的弹出窗口,但不能关闭旧的。我怎么解决这个问题?这总是会创建一个新的。
调用组件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
}
}
答案 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");
}
}