设置调度程序

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

声明 NavigationEventDispatcher

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

您应通过 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),则无论其各个子级调度程序是否处于启用状态,与该父级及其任何子级关联的所有处理程序都将被忽略。