设置调度程序

为了实现强大的导航系统,您的应用需要一种集中式方式来处理返回手势和其他导航信号。本页介绍了如何使用 NavigationEventDispatcher 在整个应用中协调和分发这些导航事件。

声明 NavigationEventDispatcher

NavigationEventDispatcherNavigationEvent 库的核心组件。它充当事件中心,可将导航相关事件(例如返回手势和导航过渡)分派给应用中已注册的监听器。组件可以订阅这些事件,以响应导航更改或其他系统驱动的导航操作。

您应通过 NavigationEventDispatcherOwner 提供 NavigationEventDispatcher 实例。这可确保应用的不同部分能够访问同一调度程序,并以一致且协调的方式观察导航事件。

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) 时,与该父调度器及其任何子调度器关联的所有处理程序都会被忽略,无论其各自的启用状态如何。