本页面由葡萄牙语机器翻译,可能存在错误。葡萄牙语版本为准。
如何在 controller 中集中管理导航
目的。 将 new X().show() 和 hide() 散布在各个屏幕中,会使 UI 与导航图耦合。一个 controller 集中管理 push/pop,提供一个用于日志/守卫的统一入口,并支持“关闭直到根屏幕”。它仅仅编排 EventsProcessor 的真实栈。
使用的 API
Window.show()/Window.hide()— 栈上的 push/pop(controller 只是委托给它们)。EventsProcessor.topWindow()— 静态方法,返回栈顶窗口(instance.windows.peek())。EventsProcessor.instance.getLastWindow()— 实例方法;返回栈的真实顶部(如果为空则返回null)。当需要检查栈中是否有内容而不抛出异常时使用。
在
EventsProcessor的源码中确认的名称:topWindow()(静态)和getLastWindow()(实例)。topWindow()执行windows.peek(),如果栈为空则抛出异常;getLastWindow()在这种情况下返回null——防御性检查时优先使用后者。
完整示例(复制、粘贴并运行)
package com.exemplo;
import dev.crossfly.ui.*;
import dev.crossfly.ui.layout.*;
/** 可执行主屏:使用 Nav 控制器压入/弹出屏幕。 */
public class MainWindow extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
add(new Label("Tela raiz"));
add(new Button("Abrir detalhe").onAction(e -> Nav.push(new OutraTela()))); // 通过控制器 push
}
}
/** 栈内屏幕:通过控制器关闭(pop)。 */
class OutraTela extends Window
{
@Override
public void onShow() throws Exception
{
super.onShow();
setLayout(new VerticalLayout());
add(new Label("Detalhe"));
add(new Button("Voltar").onAction(e -> Nav.pop())); // 通过控制器 pop
}
}
/** 控制器:对 EventsProcessor 真实栈的薄封装。 */
final class Nav
{
private Nav() {}
/** push:入栈并显示。 */
public static void push(Window w)
{
w.show();
}
/** pop:关闭栈顶窗口(若有)。 */
public static void pop()
{
Window top = EventsProcessor.instance.getLastWindow(); // null 安全
if (top != null)
top.hide();
}
/** 当前栈顶窗口(可能为 null)。 */
public static Window current()
{
return EventsProcessor.instance.getLastWindow();
}
}
下面的片段只展示核心部分。要运行它,请将其放入上面的
MainWindow骨架中。
最小片段
// 已在源码核对:EventsProcessor.topWindow()(静态)与 instance.getLastWindow()(栈空时返回 null)
public final class Nav
{
private Nav() {}
/** push:入栈并显示。 */
public static void push(Window w)
{
w.show();
}
/** pop:关闭栈顶窗口(若有)。 */
public static void pop()
{
Window top = EventsProcessor.instance.getLastWindow(); // null 安全
if (top != null)
top.hide();
}
/** 反复 pop 直到只剩 1 个窗口(根窗口)。 */
public static void popToRoot()
{
Window top;
// 只要栈中窗口多于一个,就消掉栈顶
while ((top = EventsProcessor.instance.getLastWindow()) != null
&& top != EventsProcessor.topWindow()) { top.hide(); }
// (若要"回到根",每次 hide() 弹出一个;请按你的应用调整停止条件)
}
/** 当前栈顶窗口(可能为 null)。 */
public static Window current()
{
return EventsProcessor.instance.getLastWindow();
}
}
// 在屏幕中的用法:
Nav.push(new DetalheTela());
// ...
Nav.pop();
最佳实践:
- 不要重新实现栈:
EventsProcessor已经是唯一的事实来源。controller 是show()/hide()之上的一个薄门面。 - 导航守卫(例如:“有未保存的更改吗?”)在这里很自然:在
pop()之前检查,如有必要,弹出一个确认Alert。 - 当栈可能为空时要小心
topWindow()——它执行peek()并会抛出异常。对于防御性代码请使用getLastWindow()。
深入了解
这个页面有帮助吗?感谢你的反馈!