Как настроить диспетчера

Чтобы реализовать надежную систему навигации, вашему приложению нужен централизованный способ обработки жестов назад и других навигационных сигналов. На этой странице описано, как использовать NavigationEventDispatcher для координации и распределения этих событий навигации в приложении.

Объявить NavigationEventDispatcher

NavigationEventDispatcher – это основной компонент библиотеки NavigationEvent. Он действует как центр событий, который отправляет события, связанные с навигацией, такие как жесты назад и переходы навигации, зарегистрированным слушателям в вашем приложении. Компоненты могут подписываться на эти события, чтобы реагировать на изменения навигации или другие действия навигации, управляемые системой.

Экземпляры NavigationEventDispatcher должны предоставляться через NavigationEventDispatcherOwner. Это гарантирует, что разные части вашего приложения смогут получить доступ к одному и тому же диспетчеру и наблюдать за событиями навигации согласованным и скоординированным образом.

class MyComponent: NavigationEventDispatcherOwner {
    override val navigationEventDispatcher: NavigationEventDispatcher =
        NavigationEventDispatcher()
}

Если вы находитесь внутри ComponentActivity, то вместо реализации собственного диспетчера можете получить предоставленный вам.

class MyCustomActivity : ComponentActivity() {
    fun addMyHandler() {
        // navigationEventDispatcher provided by the ComponentActivity
        navigationEventDispatcher.addHandler(myNavigationEventHandler)
    }
}

Добавление: NavigationEventInput

После регистрации обработчика вы сможете получать события. Однако вам нужно указать источник, из которого генерируются события, с помощью NavigationEventInput.

NavigationEventInput – это компонент, который получает необработанные системные входные данные и преобразует их в стандартный NavigationEvent, который отправляется в NavigationEventDispatcher.

Ниже приведен пример специальной реализации NavigationEventInput:

public class MyInput : NavigationEventInput() {
    @MainThread
    public fun backStarted(event: NavigationEvent) {
        dispatchOnBackStarted(event)
    }

    @MainThread
    public fun backProgressed(event: NavigationEvent) {
        dispatchOnBackProgressed(event)
    }

    @MainThread
    public fun backCancelled() {
        dispatchOnBackCancelled()
    }

    @MainThread
    public fun backCompleted() {
        dispatchOnBackCompleted()
    }
}

Затем передайте эти данные диспетчеру:

navigationEventDispatcher.addInput(MyInput())

Очистка ресурсов с помощью dispose()

Чтобы избежать утечек памяти в динамическом интерфейсе, каждый созданный экземпляр NavigationEventDispatcher должен быть явно удален из иерархии с помощью метода dispose(), когда связанный с ним компонент уничтожается:

navigationEventDispatcher.dispose()

Метод dispose() обеспечивает каскадную очистку, последовательно удаляя диспетчер и все его дочерние элементы, что гарантирует отмену регистрации всех связанных обработчиков в общей системе.

Иерархия и управление диспетчерами

NavigationEventDispatcher поддерживает иерархию родительских и дочерних элементов, позволяя компонентам, вложенным глубоко в пользовательский интерфейс (например, вложенным NavHost или диалоговым окнам), участвовать в обработке событий навигации.

Как создать дочерний диспетчер

Дочерний диспетчер создается путем передачи ссылки на родительский диспетчер во время создания. Все диспетчеры в иерархии используют один и тот же объект NavigationEventProcessor, чтобы поддерживать глобальный порядок событий LIFO (последним пришел – первым ушел) на основе приоритета.

Иерархическое включение

Диспетчер включает свойство isEnabled, которое позволяет разработчикам включать или отключать сразу все поддерево обработчиков.

Если родительский диспетчер отключен (isEnabled = false), все обработчики, связанные с этим родителем и любым из его дочерних элементов, будут игнорироваться независимо от их индивидуального состояния включения.