Навигатор#
Класс, отвечающий за стандартное поведение пользовательского экрана:
компоновка панелей и текущего представления
перерисовка элементов
блокировка экрана
показ диалогов
работа с меню и внутренней шиной событий
и т.п.
Контроллер представления получает доступ к навигатору через свойство navigator.
Контроллер представления может изменить стандартное поведение, переопределив соответствующие методы.
Перечень методов для переопределения определён в интерфейсе NavigableVcp.
Классы, реализующие навигатор:
GsBottomNavigationBarViewGsDrawerNavigationView
Отображение экрана#
Экран отрисовывается на основе следующих элементов:
Контроллер представления
Используется контроллер представления верхнего состояния в стеке состояний.View— разметка на основе библиотеки ComposeNavigableVcp— инъекция зависимости в навигатор, которая может переопределить стандартное поведение:состав меню
видимость меню
FAB
наименование экрана
TopBarBottomBarDrawer
Только в случаеGsDrawerNavigationViewдиалоговые окна
загрузочные окна
В стеке никогда не хранится более одного экрана для каждого SmState.
Повторный вызов State просто обновляет существующий элемент.
TopBar#
Плашка вверху экрана, используется для:
навигационной кнопки
Часто используется для кнопки вызова меню или кнопки «назад».наименования экрана
кнопок действий
Для понимания принципов использования смотрите AppBar в Google Material Design.
Функции навигатора:
hideTopAppBar()showTopAppBar()topGsMenuItems
BottomBar#
Плашка внизу экрана, используется для:
кнопок глобальной навигации
Для понимания принципов использования смотрите NavigationBar в Google Material Design.
Функции навигатора:
hideBottomBar()showBottomBar()setBadgeFor(vciClassName, value)
В случаеGsBottomNavigationBarViewзадаёт индикацию глобальным переходам.
Drawer#
Выезжающая боковая панель, используется для глобальных переходов и действий.
Список глобальных переходов#
Задаёт доступные переходы в состояния, которые пользователь может выполнить из
Drawer или BottomBar в зависимости от используемого навигатора.
Функции навигатора:
setBaseMenu()
FAB#
Плавающая кнопка, которая размещается поверх интерфейса и предназначена для выполнения главного действия на экране.
По умолчанию иконка + выключена. Переопределяется в NavigableVcp.
Блокировка и диалоги#
Функции навигатора:
lock("Sync…")— показывает полноэкранный индикатор и блокирует навигационные жестыunlock()— снимает блокировку
Это удобно для сетевых операций, которые важно завершить без выхода пользователя.createDialog(title, msg, …)— упрощённый API для простых диалогов «OK/Cancel»
Данные хранятся вnavigator.simpleDialog, Compose-слой реагирует автоматически.
Шина событий#
Навигатор предоставляет компактную шину событий (на основе Flow Kotlin) между независимыми
контроллерами представлений без глобальных синглтонов.
Функции контроллера представления:
subscribeEventBus// подписка vci.subscribeEventBus<MyPayload>("UpdateEvent") { payload -> // реакция }
sendEventBus// публикация vci.sendEventBus("UpdateEvent", MyPayload(...)) { error -> // обработка ошибок }
Примечание
За каждым именем события хранится
SharedFlow.При закрытии экрана
closeEventBus(name)автоматически отменяет подписку, предотвращая утечки.
Индикатор синхронизации#
Функции навигатора:
setNeedSync(boolean)
Включает или выключает иконку «обновить» вTopBar.onClickSyncBtn
Передаёт обработчик в текущийVCI; типичная реализация — вызовpostSharedTaskдля синхронизации с сервером.
Примечание#
Пример расширения Navigator#
Пример расширения для работы с NFC:
class MyNavigator :
NavigatorCtrl(),
NavigatorNfc {
override fun <T> onNfcRead(
data: String,
ss: SmStateSubject<out SmState>,
onRead: (String) -> Unit,
onShow: (T) -> Unit
) {
// обработка NFC-данных
}
}
interface NavigatorNfc {
fun <T> onNfcRead(
data: String,
ss: SmStateSubject<out SmState>,
onRead: (String) -> Unit = {},
onShow: (T) -> Unit = {}
)
}
// MainActivity
navigator.onNfcRead<Map<String, String>>(it, getSts()) { data ->
nfcData = data
showNfcDialog.value = true
}
Пример MainActivity#
class MainActivity : GsBaseActivity<AppNavigator>() {
@Composable
override fun ContentView(navigatorCtrl: NavigatorCtrl) {
AppTheme {
navigator.setBaseMenu(
listOf(
DrawerItem("Users") { getSts().postCallState<UsersState>() },
DrawerItem("Settings") { getSts().postCallState<SettingsState>() }
)
)
GsDrawerNavigatorView(navigatorCtrl)
}
}
override fun provideNavigator() = AppNavigator()
override fun provideDatabase() = AppDatabase.getInstance(this)
override fun provideFirstState() = UsersState()
}
Главная Activity предоставляет Navigator, базовое меню и первое состояние; дальше всё управление переходит к StateManager и VCI-слою.
Навигационный слой GMF изолирует UI-логику от бизнес-кода: контроллеры формируют интеракции, а Navigator обеспечивает плавные переходы, блокировки, меню и коммуникацию между экранами — всё в нескольких вызовах без шаблонного кода.