问题描述
我正在尝试使用启用了玻璃和自动隐藏功能的GWT PopupPanel(或DialogBox)在移动设备上创建上下文操作菜单,但是当用户要关闭操作菜单弹出窗口时(通过在玻璃上点击),我遇到了问题弹出式窗口中的内容,在内容之外触发自动隐藏):当关闭弹出式窗口时,基础小部件(在玻璃下面)也将接收tap事件。例如,如果在该位置有一个打开新视图/窗口的按钮,则单击该按钮并执行其单击处理程序。
我的代码:
public void onModuleLoad() {
Button button = new Button("Test");
button.addClickHandler(cl -> {
Label lb = new Label("This is the content");
lb.getElement().getStyle().setBackgroundColor("#fff");
lb.setSize("200px","80px");
DialogBox pop = new DialogBox();
pop.setAutoHideEnabled(true);
pop.setGlassEnabled(true);
pop.setWidget(lb);
pop.center();
});
Button buttonBehindGlass = new Button("Test over");
buttonBehindGlass.addClickHandler(cl -> {
Window.alert("Action 2");
});
RootPanel.get().add(button);
RootPanel.get().add(buttonBehindGlass);
}
在此示例中,如果您打开弹出窗口,然后在玻璃上的“ buttonBehindGlass”小部件上方单击/轻击内容,您会注意到弹出窗口关闭并且同时单击了“ buttonBehindGlass”
有什么办法可以避免这种情况?
我在启用了响应/触摸模式的Android和Chrome开发工具上进行了测试。这个问题不会出现在台式机上,一切都很好。
解决方法
创建您自己的对话框,基于 GWT
public class DialogBoxExtended extends DialogBox {
@Override
protected void onPreviewNativeEvent(NativePreviewEvent event) {
super.onPreviewNativeEvent(event);
// check if the event does not target the popup
Event nativeEvent = Event.as(event.getNativeEvent());
if (!eventTargetsPopup(nativeEvent)) {
// on click,touch end,etc. close the dialog box
switch (event.getTypeInt()) {
case Event.ONMOUSEDOWN:
case Event.ONCLICK:
case Event.ONTOUCHEND:
hide();
break;
}
}
}
/**
* Does the event target this popup?
*
* @param event the native event
* @return true if the event targets the popup
*/
private boolean eventTargetsPopup(NativeEvent event) {
EventTarget target = event.getEventTarget();
if (Element.is(target)) {
return getElement().isOrHasChild(Element.as(target));
}
return false;
}
}
禁用自动隐藏并使用您创建的对话框
public void onModuleLoad() {
Button button = new Button("Test");
button.addClickHandler(cl -> {
Label lb = new Label("This is the content");
lb.getElement().getStyle().setBackgroundColor("#fff");
lb.setSize("200px","80px");
DialogBox pop = new DialogBoxExtended();
pop.setAutoHideEnabled(false);
pop.setGlassEnabled(true);
pop.setWidget(lb);
pop.center();
});
Button buttonBehindGlass = new Button("Test over");
buttonBehindGlass.addClickHandler(cl -> {
Window.alert("Action 2");
});
RootPanel.get().add(button);
RootPanel.get().add(buttonBehindGlass);
}
它现在按预期工作。
启用自动隐藏后,事件会被处理但留给其他处理程序使用 - 这就是事件到达底层按钮的原因。在桌面上,这不是问题,因为正在考虑 Event.ONMOUSEUP
,但在移动/触摸模式下,Event.ONTOUCHEND
被触发。