恢复所有分层窗格组件的位置并重新粉刷它们

时间:2018-10-04 10:44:46

标签: codenameone

这个问题与此有关:Keep Codename One components in invalid positions after app stop/resume

在链接的问题中,提出的解决方案是使用假布局。我尝试过,但是当我尝试恢复原始布局时会产生副作用。

我尝试了一种完全不同的方法,该方法在Android上效果很好。 我的问题是,为什么以下代码仅在Android上能很好地工作(在iPhone上不起作用,似乎忽略了该代码),并且是否有小的更改使该代码在iPhone上也能工作。

代码:

private Map<Component, Dimension> layeredPaneCmps = new HashMap<>();

public void start() {
    if (current != null) {
        current.show();
        layeredPaneRestore(); // it works on Android, but not on iOS
        return;
    }
    [...]
}

public void stop() {
    current = getCurrentForm();
    if (current instanceof Dialog) {
        ((Dialog) current).dispose();
        current = getCurrentForm();
    }
    layeredPaneSave(null);
}

/**
 * Save the position of all layered pane components in a recursive way: just
 * invoke with null as cnt.
 *
 * @param cnt
 */
private void layeredPaneSave(Container cnt) {
    if (cnt == null) {
        layeredPaneCmps.clear();
        cnt = Display.getInstance().getCurrent().getLayeredPane(this.getClass(), true);
    }
    for (int i = 0; i < cnt.getComponentCount(); i++) {
        layeredPaneCmps.put(cnt.getComponentAt(i), new Dimension(cnt.getComponentAt(i).getX(), cnt.getComponentAt(i).getY()));
        if (cnt.getComponentAt(i) instanceof Container) {
            layeredPaneSave((Container) cnt.getComponentAt(i));
        }
    }
}

/**
 * Restores all layered pane components in their position and repaints them.
 */
private void layeredPaneRestore() {
    Container layeredPane = Display.getInstance().getCurrent().getLayeredPane(this.getClass(), true);
    for (Component cmp : layeredPaneCmps.keySet()) {
        cmp.setX(layeredPaneCmps.get(cmp).getWidth());
        cmp.setY(layeredPaneCmps.get(cmp).getHeight());
        cmp.repaint();
    }
    layeredPane.repaint();
}

1 个答案:

答案 0 :(得分:1)

Android和iOS具有非常不同的挂起/恢复行为,其中iOS尝试最小化重绘和背景,而Android不断挂起/恢复。我建议登录stop() / start()方法以确保它们不会被多次调用。

请注意,您不应调用repaint(),它会为您调用。由于repaint()可能会触发布局,因此这可能是一个问题。父组件的repaint()也会循环绘制组件,因此layeredPane就足够了,也不需要cmp.repaint();