简体   繁体   English

Gluon Mobile Charm 5.0无法隐藏图层

[英]Gluon Mobile Charm 5.0 Cannot Hide Layer

I have a loading gif for all backend requests. 我有所有后端请求的加载gif。 Prior to Charm 5.0.0, it worked fine in which the loading gif would show, backend would finish what it needed to, then the loading gif would be hidden. 在Charm 5.0.0之前,它可以正常工作,显示加载的gif,后端完成所需的操作,然后隐藏加载的gif。 Now, the loading gif shows, but it doesn't hide. 现在,显示了加载的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);
            }
        });

I have a couple of utility methods that show and hide the loader: 我有几个实用程序方法可以显示和隐藏加载程序:

public void showLoader() {
    MobileApplication.getInstance().showLayer(App.LOADING_GIF);
}

public void hideLoader() {
    MobileApplication.getInstance().hideLayer(App.LOADING_GIF);
}

Interestingly, the custom timeout I created (to hide the loader in case there is a stall in the backend) doesn't hide the layer either. 有趣的是,我创建的自定义超时(以隐藏加载程序,以防后端出现停顿)也不会隐藏该层。

There is an issue with your code: you are overriding Layer::layoutChildren , but you are not calling super.layoutChildren() . 您的代码有一个问题:您正在覆盖Layer::layoutChildren ,但是您没有在调用super.layoutChildren()

If you check the JavaDoc : 如果您检查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正常运行,应注意在覆盖的方法中调用此方法。

This means that you are getting rid of some important parts of the Layer control, such as animations, events and visibility control. 这意味着您将摆脱“图层”控件的一些重要部分,例如动画,事件和可见性控件。

This should work: 这应该工作:

@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);
}

On a side note, for the hide transition, you should use setHideTransitionFactory . 另外,对于隐藏过渡,应使用setHideTransitionFactory

So this is what I have done to solve this. 所以这就是我为解决这个问题所做的。 From the Gluon Docs on the hide() method: hide()方法的Gluon Docs中:

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. 只有在LifecycleEvent.SHOWN被触发后才应注意调用此方法。

Thus, I was realizing that the response from the backend was coming before the layer was fully shown. 因此,我意识到来自后端的响应是在完全显示该层之前出现的。 Thus, I modified the overridden hide() method as follows: 因此,我修改了覆盖的hide()方法,如下所示:

@Override
public void hide() {
   if (this.isShowing()) {
     this.setOnShown(e -> {
        this.setBackgroundFade(0.0);
        super.hide();
     });
   } else {
     super.hide();
   }
}

So if the layer is still in LifecycleEvent.SHOWING mode when being told to hide, make sure that it hides when it is shown. 因此,如果在被告知要隐藏时该图层仍处于LifecycleEvent.SHOWING模式,请确保在显示该图层时将其隐藏。 Otherwise it is already shown so hide it. 否则它已经显示,所以将其隐藏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM