Gluon 重用视图并优先使用受保护的事件挂钩进行填充
Gluon reusing view and populating prefeably using a protected event hook
在 Gluon 中注册一个视图工厂,Gluon 在需要时使用它来创建视图。
addViewFactory(HOME_VIEW, () -> new LoginView());
addViewFactory(SelectView.class.getSimpleName(), () -> new SelectView());
然后您可以使用以下方式切换视图:
MobileApplication.getInstance().switchView(SelectView.class.getSimpleName());
如果您在 SelectView 上并且想返回,您可以使用这个:
MobileApplication.getInstance().switchToPreviousView();
现在问题来了:在转到 SelectView 后,回到上一个,然后再回到 SelectView,Gluon 决定不创建新视图,而是重用现有视图。这并不是真正的问题,甚至可能是一件好事,它只是意味着初始化代码需要拆分为 "createView" 和 "populateView" 方法。在 onShowing 事件中调用 populateView 方法。一切顺利。
我的问题是我似乎无法为此覆盖 'onShowing()' 方法,但需要使用 setOnShowing 方法实际注册。这似乎不仅偏离了标准的做事方式(例如重写 updateAppBar 方法),而且还意味着声明一个事件挂钩供内部使用,实际上更适合外部使用(外部侦听器)。
我是不是做错了什么?
- Gluon 是否应该在重新访问时创建一个新视图?
- 或者是否有可以覆盖的 onShowing() 方法?
出于性能原因,Gluon 的视图被缓存。每当您添加一个视图时,您都会提供一个供应商,它将在需要该视图时调用。此时,视图将被添加到缓存中,下次您需要相同的视图时,将从该缓存中检索它。只有当它没有找到时,例如在内存限制下它可以被删除,它会从供应商那里重新创建。
因此,正如您所说,只为视图编写一次代码(您的 "createView")是有意义的,该代码在该视图的整个生命周期中保持不变,并且调用的可变代码也是如此每次显示视图(您的 "populateView"),但从缓存中获取,而不调用其构造函数。
对于有多个视图的项目,使用 MVP 方法、FXML 和 Gluon Glisten-Afterburner 框架会更方便。
在这种情况下,视图创建并注册一次,可以使用presenter通过initialize()
定义视图。
如果您检查任何使用此方法的示例(例如 Notes 应用程序),您将看到:
注册视图(Notes 视图是一个 AppView
,它创建一个从 FXMLView
扩展的 GluonView
):
public static final AppView NOTES_VIEW = view("Notes", NotesPresenter.class, MaterialDesignIcon.HOME, SHOW_IN_DRAWER, HOME_VIEW, SKIP_VIEW_STACK);
创建演示者:
public class NotesPresenter extends GluonPresenter<NotesApp> {
@FXML private View notes;
public void initialize() {
// one time only code
...
// code required each time the view is displayed
}
}
现在您可以使用视图的某些 properties,例如 showingProperty()
、onShowingProperty()
、onShownProperty()
添加无法从外部删除或覆盖的侦听器查看:
public void initialize() {
notes.showingProperty().addListener((obs, oldValue, newValue) -> {
if (newValue) {
// update appBar
AppBar appBar = getApp().getAppBar();
...
}
});
}
同样可以应用于常规视图,当然:
View view = new View() {
private final Label label;
{
label = new Label("some text");
showingProperty().addListener((obs, ov, nv) -> {
if (nv) {
// update view
label.setText("new text");
}
});
onShownProperty().addListener((obs, ov, nv) -> {
// add something when view is fully shown
});
onHiddenProperty().addListener((obs, ov, nv) -> {
// remove something when view is hidden
});
}
@Override
protected void updateAppBar(AppBar appBar) {
...
}
};
在 Gluon 中注册一个视图工厂,Gluon 在需要时使用它来创建视图。
addViewFactory(HOME_VIEW, () -> new LoginView());
addViewFactory(SelectView.class.getSimpleName(), () -> new SelectView());
然后您可以使用以下方式切换视图:
MobileApplication.getInstance().switchView(SelectView.class.getSimpleName());
如果您在 SelectView 上并且想返回,您可以使用这个:
MobileApplication.getInstance().switchToPreviousView();
现在问题来了:在转到 SelectView 后,回到上一个,然后再回到 SelectView,Gluon 决定不创建新视图,而是重用现有视图。这并不是真正的问题,甚至可能是一件好事,它只是意味着初始化代码需要拆分为 "createView" 和 "populateView" 方法。在 onShowing 事件中调用 populateView 方法。一切顺利。
我的问题是我似乎无法为此覆盖 'onShowing()' 方法,但需要使用 setOnShowing 方法实际注册。这似乎不仅偏离了标准的做事方式(例如重写 updateAppBar 方法),而且还意味着声明一个事件挂钩供内部使用,实际上更适合外部使用(外部侦听器)。
我是不是做错了什么?
- Gluon 是否应该在重新访问时创建一个新视图?
- 或者是否有可以覆盖的 onShowing() 方法?
出于性能原因,Gluon 的视图被缓存。每当您添加一个视图时,您都会提供一个供应商,它将在需要该视图时调用。此时,视图将被添加到缓存中,下次您需要相同的视图时,将从该缓存中检索它。只有当它没有找到时,例如在内存限制下它可以被删除,它会从供应商那里重新创建。
因此,正如您所说,只为视图编写一次代码(您的 "createView")是有意义的,该代码在该视图的整个生命周期中保持不变,并且调用的可变代码也是如此每次显示视图(您的 "populateView"),但从缓存中获取,而不调用其构造函数。
对于有多个视图的项目,使用 MVP 方法、FXML 和 Gluon Glisten-Afterburner 框架会更方便。
在这种情况下,视图创建并注册一次,可以使用presenter通过initialize()
定义视图。
如果您检查任何使用此方法的示例(例如 Notes 应用程序),您将看到:
注册视图(Notes 视图是一个
AppView
,它创建一个从FXMLView
扩展的GluonView
):public static final AppView NOTES_VIEW = view("Notes", NotesPresenter.class, MaterialDesignIcon.HOME, SHOW_IN_DRAWER, HOME_VIEW, SKIP_VIEW_STACK);
创建演示者:
public class NotesPresenter extends GluonPresenter<NotesApp> { @FXML private View notes; public void initialize() { // one time only code ... // code required each time the view is displayed } }
现在您可以使用视图的某些 properties,例如 showingProperty()
、onShowingProperty()
、onShownProperty()
添加无法从外部删除或覆盖的侦听器查看:
public void initialize() {
notes.showingProperty().addListener((obs, oldValue, newValue) -> {
if (newValue) {
// update appBar
AppBar appBar = getApp().getAppBar();
...
}
});
}
同样可以应用于常规视图,当然:
View view = new View() {
private final Label label;
{
label = new Label("some text");
showingProperty().addListener((obs, ov, nv) -> {
if (nv) {
// update view
label.setText("new text");
}
});
onShownProperty().addListener((obs, ov, nv) -> {
// add something when view is fully shown
});
onHiddenProperty().addListener((obs, ov, nv) -> {
// remove something when view is hidden
});
}
@Override
protected void updateAppBar(AppBar appBar) {
...
}
};