設定調度員

如要實作穩健的導覽系統,應用程式需要集中處理返回手勢和其他導覽信號。本頁說明如何使用 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() 清除資源

為避免動態 UI 發生記憶體流失,當與 NavigationEventDispatcher 執行個體繫結的元件遭到毀損時,必須使用 dispose() 方法,從階層中明確移除每個建立的 NavigationEventDispatcher 執行個體:

navigationEventDispatcher.dispose()

dispose() 方法會反覆移除調度器及其所有後代 (子項和孫項),確保所有相關聯的處理常式都已從共用系統取消註冊,藉此確保連鎖清除作業。

調度員階層和控制

NavigationEventDispatcher 支援父項/子項階層,因此 UI 中深層巢狀結構的元件 (例如巢狀 NavHost 或對話方塊) 也能參與導覽事件處理。

建立子項調度工具

建立子項調度器時,請將參照傳遞至父項調度器。階層中的所有調度器都會共用相同的 NavigationEventProcessor,以根據優先順序維持全域「後進先出」(LIFO) 事件順序。

階層式啟用

分派器包含 isEnabled 屬性,可讓開發人員一次啟用或停用整個處理常式子樹狀結構。

如果停用父項調度器 (isEnabled = false),系統會忽略與該父項和任何子項相關聯的所有處理常式,無論個別啟用狀態為何。