Gluon Mobile Charm 5.0 无法隐藏图层
Gluon Mobile Charm 5.0 Cannot Hide Layer
我有一个用于所有后端请求的加载 gif。在 Charm 5.0.0 之前,它工作正常,其中加载 gif 会显示,后端会完成它需要的,然后加载 gif 会被隐藏。现在,加载 gif 显示,但它不会隐藏。
addLayerFactory(LOADING_GIF, () -> new Layer() {
private final Node root;
private final double sizeX = getGlassPane().getWidth();
private final double sizeY = getGlassPane().getHeight();
{
ProgressIndicator loading = new ProgressIndicator();
loading.setRadius(50);
loading.setStyle("-fx-text-fill:white");
root = new StackPane(loading);
root.setStyle("-fx-background-color: rgba(0,0,0,0);");
getChildren().add(root);
this.setStyle("-fx-background-color:rgba(255,255,255,0.7)");
this.setShowTransitionFactory(v -> {
FadeInTransition ft = new FadeInTransition(v);
ft.setRate(2);
return ft;
});
}
@Override
public void show() {
this.setBackgroundFade(0.0);
super.show();
Layer pane = this;
Task<Integer> task = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
int iterations = 0;
int max = DataService.readOutTime / 1000;
while (iterations <= max) {
Thread.sleep(1000);
iterations++;
}
Platform.runLater(new Runnable() {
@Override
public void run() {
if (pane.isVisible()) {
pane.setShowTransitionFactory(v -> {
FadeOutTransition ft = new FadeOutTransition(v);
ft.setRate(2);
return ft;
});
pane.hide();
MobileApplication.getInstance().showMessage("There was an error in sending your data.");
}
}
});
return iterations;
}
};
Thread thread = new Thread(task);
thread.start();
}
@Override
public void hide() {
this.setBackgroundFade(0.0);
super.hide();
}
@Override
public void layoutChildren() {
root.setVisible(isShowing());
if (!isShowing()) {
return;
}
root.resize(sizeX, sizeY);
resizeRelocate((getGlassPane().getWidth() - sizeX) / 2, (getGlassPane().getHeight() - sizeY) / 2, sizeX, sizeY);
}
});
我有几个显示和隐藏加载程序的实用方法:
public void showLoader() {
MobileApplication.getInstance().showLayer(App.LOADING_GIF);
}
public void hideLoader() {
MobileApplication.getInstance().hideLayer(App.LOADING_GIF);
}
有趣的是,我创建的自定义超时(隐藏加载程序以防后端出现停顿)也没有隐藏图层。
您的代码存在问题:您覆盖了 Layer::layoutChildren
,但没有调用 super.layoutChildren()
。
如果你勾选 JavaDoc:
Override this method to add the layout logic for your layer. Care should be taken to call this method in overriden methods for proper functioning of the Layer.
这意味着您将摆脱 Layer 控件的一些重要部分,例如动画、事件和可见性控制。
这应该有效:
@Override
public void layoutChildren() {
super.layoutChildren();
root.setVisible(isShowing());
if (!isShowing()) {
return;
}
root.resize(sizeX, sizeY);
resizeRelocate(getGlassPane().getWidth() - sizeX) / 2, getGlassPane().getHeight() - sizeY) / 2, sizeX, sizeY);
}
附带说明一下,对于隐藏过渡,您应该使用 setHideTransitionFactory
。
这就是我为解决这个问题所做的工作。来自 hide()
方法的 Gluon 文档:
If this layer is showing, calling this method will hide it. If a hide transition is present, it is played before hiding the Layer. Care should be taken to call this only once LifecycleEvent.SHOWN has been fired.
因此,我意识到在图层完全显示之前来自后端的响应已经到来。因此,我修改了覆盖的 hide()
方法如下:
@Override
public void hide() {
if (this.isShowing()) {
this.setOnShown(e -> {
this.setBackgroundFade(0.0);
super.hide();
});
} else {
super.hide();
}
}
因此,如果图层在被告知隐藏时仍处于 LifecycleEvent.SHOWING 模式,请确保它在显示时隐藏。否则它已经显示,所以隐藏它。
我有一个用于所有后端请求的加载 gif。在 Charm 5.0.0 之前,它工作正常,其中加载 gif 会显示,后端会完成它需要的,然后加载 gif 会被隐藏。现在,加载 gif 显示,但它不会隐藏。
addLayerFactory(LOADING_GIF, () -> new Layer() {
private final Node root;
private final double sizeX = getGlassPane().getWidth();
private final double sizeY = getGlassPane().getHeight();
{
ProgressIndicator loading = new ProgressIndicator();
loading.setRadius(50);
loading.setStyle("-fx-text-fill:white");
root = new StackPane(loading);
root.setStyle("-fx-background-color: rgba(0,0,0,0);");
getChildren().add(root);
this.setStyle("-fx-background-color:rgba(255,255,255,0.7)");
this.setShowTransitionFactory(v -> {
FadeInTransition ft = new FadeInTransition(v);
ft.setRate(2);
return ft;
});
}
@Override
public void show() {
this.setBackgroundFade(0.0);
super.show();
Layer pane = this;
Task<Integer> task = new Task<Integer>() {
@Override
protected Integer call() throws Exception {
int iterations = 0;
int max = DataService.readOutTime / 1000;
while (iterations <= max) {
Thread.sleep(1000);
iterations++;
}
Platform.runLater(new Runnable() {
@Override
public void run() {
if (pane.isVisible()) {
pane.setShowTransitionFactory(v -> {
FadeOutTransition ft = new FadeOutTransition(v);
ft.setRate(2);
return ft;
});
pane.hide();
MobileApplication.getInstance().showMessage("There was an error in sending your data.");
}
}
});
return iterations;
}
};
Thread thread = new Thread(task);
thread.start();
}
@Override
public void hide() {
this.setBackgroundFade(0.0);
super.hide();
}
@Override
public void layoutChildren() {
root.setVisible(isShowing());
if (!isShowing()) {
return;
}
root.resize(sizeX, sizeY);
resizeRelocate((getGlassPane().getWidth() - sizeX) / 2, (getGlassPane().getHeight() - sizeY) / 2, sizeX, sizeY);
}
});
我有几个显示和隐藏加载程序的实用方法:
public void showLoader() {
MobileApplication.getInstance().showLayer(App.LOADING_GIF);
}
public void hideLoader() {
MobileApplication.getInstance().hideLayer(App.LOADING_GIF);
}
有趣的是,我创建的自定义超时(隐藏加载程序以防后端出现停顿)也没有隐藏图层。
您的代码存在问题:您覆盖了 Layer::layoutChildren
,但没有调用 super.layoutChildren()
。
如果你勾选 JavaDoc:
Override this method to add the layout logic for your layer. Care should be taken to call this method in overriden methods for proper functioning of the Layer.
这意味着您将摆脱 Layer 控件的一些重要部分,例如动画、事件和可见性控制。
这应该有效:
@Override
public void layoutChildren() {
super.layoutChildren();
root.setVisible(isShowing());
if (!isShowing()) {
return;
}
root.resize(sizeX, sizeY);
resizeRelocate(getGlassPane().getWidth() - sizeX) / 2, getGlassPane().getHeight() - sizeY) / 2, sizeX, sizeY);
}
附带说明一下,对于隐藏过渡,您应该使用 setHideTransitionFactory
。
这就是我为解决这个问题所做的工作。来自 hide()
方法的 Gluon 文档:
If this layer is showing, calling this method will hide it. If a hide transition is present, it is played before hiding the Layer. Care should be taken to call this only once LifecycleEvent.SHOWN has been fired.
因此,我意识到在图层完全显示之前来自后端的响应已经到来。因此,我修改了覆盖的 hide()
方法如下:
@Override
public void hide() {
if (this.isShowing()) {
this.setOnShown(e -> {
this.setBackgroundFade(0.0);
super.hide();
});
} else {
super.hide();
}
}
因此,如果图层在被告知隐藏时仍处于 LifecycleEvent.SHOWING 模式,请确保它在显示时隐藏。否则它已经显示,所以隐藏它。