Gluon重用视图并使用受保护的事件挂钩填充

时间:2018-11-05 08:34:01

标签: gluon gluon-mobile

在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决定不创建新视图,而是重用现有视图。这并不是一个真正的问题,甚至可能不是一件好事,它只是意味着init代码需要分为“ createView”和“ populateView”方法。在onShowing事件中调用populateView方法。一切都很好。

我的问题是我似乎无法为此覆盖'onShowing()'方法,但实际上需要使用setOnShowing方法进行注册。这似乎不仅与标准的处理方式有所偏离(例如,像重写updateAppBar方法一样),而且还意味着声明内部使用的事件钩子,实际上更适合外部使用(由外部侦听器使用)。 / p>

我做错什么了吗?

  • 重新访问时Gluon是否应创建一个新视图?
  • 还是有onShowing()方法要覆盖?

1 个答案:

答案 0 :(得分:1)

出于性能原因,对Gluon的视图进行了缓存。每当您添加一个视图时,即在提供一个供应商,当需要该视图时将调用该供应商。此时,视图将被添加到缓存中,下次您需要相同的视图时,将从该缓存中检索该视图。只有在找不到它的情况下(例如在内存限制下),才能将其删除,然后才从供应商处再次创建它。

因此,正如您所说,有意义的是,只有一个视图代码(您的“ createView”),在该视图的整个生命周期中保持不变,并且每次视图都调用可变代码显示(您的“ populateView”),但从缓存中获取,而没有调用其构造函数。

对于具有多个视图的项目,使用FVP和Gluon Glisten-Afterburner框架的MVP方法更为方便。

在这种情况下,视图仅创建和注册一次,演示者可用于通过initialize()定义视图。

如果您检查使用此方法的任何示例(例如Notes应用程序),则会看到:

  • 注册视图(注释视图是一个AppView,它创建了一个从GluonView延伸的FXMLView):

    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) {
        ...
    }

};