Gluon повторно использует представление и предпочтительно заполняет его, используя защищенный обработчик событий - PullRequest
0 голосов
/ 05 ноября 2018

В 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». Метод populateView вызывается в событии onShowing. Все хорошо.

Моя проблема в том, что я не могу переопределить метод onShowing () для этого, но мне нужно зарегистрироваться, используя метод setOnShowing. Кажется, что это не только отклонение от стандартного способа работы (например, переопределение метода updateAppBar), но это также означает требование перехвата события для внутреннего использования, которое действительно больше предназначено для внешнего использования (внешними слушателями).

Я что-то не так делаю?

  • Должен ли Глуон создать новый вид при повторном посещении?
  • Или есть метод onShowing () для переопределения?

1 Ответ

0 голосов
/ 05 ноября 2018

Представления Gluon кэшируются по соображениям производительности. Всякий раз, когда вы добавляете одно представление, вы предоставляете поставщика, который будет вызываться, когда представление требуется. На этом этапе представление будет добавлено в кеш, и в следующий раз, когда вам понадобится такое же представление, оно будет извлечено из этого кеша. Только если он не найден, например, из-за ограничений памяти, его можно удалить, он снова будет создан у поставщика.

Итак, как вы говорите, имеет смысл иметь единовременный код для представления (ваш «createView»), который остается неизменным на протяжении всего жизненного цикла этого представления, а также изменяемый код, который вызывается каждый раз, когда представление отображается (ваш «populateView»), но берется из кэша, без вызова его конструктора.

Для проектов с несколькими представлениями удобнее использовать подход MVP с FXML и структурой Gluon Glisten-Afterburner.

В этом случае вид создается и регистрируется один раз, и докладчик может быть использован для определения вида с помощью initialize().

Если вы проверите любой из примеров, использующих этот подход (например, приложение Notes ), вы увидите:

  • Представление реестра (представление 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
        }
    
    }
    

Теперь вы можете использовать некоторые из свойств View , например 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) {
        ...
    }

};     
...