navigationevent

  
Navigation Event 库提供了一个 KMP-first API,用于处理系统返回以及预测性返回
最近更新时间 稳定版 候选版 Beta 版 Alpha 版
2025 年 8 月 13 日 - - - 1.0.0-alpha06

声明依赖项

如需添加 navigationevent 的依赖项,您必须将 Google Maven 制品库添加到项目中。如需了解详情,请参阅 Google 的 Maven 代码库

在应用或模块的 build.gradle 文件中添加所需工件的依赖项:

Groovy

dependencies {
    implementation "androidx.navigationevent:navigationevent:1.0.0-alpha06"
}

Kotlin

dependencies {
    implementation("androidx.navigationevent:navigationevent:1.0.0-alpha06")
}

如需详细了解依赖项,请参阅添加 build 依赖项

反馈

您的反馈将帮助我们改进 Jetpack。如果您发现了新问题,或对此库有任何改进建议,请告诉我们。创建新问题前,请先查看此库中的现有问题。您可以点击星标按钮,为现有问题投票。

创建新问题

如需了解详情,请参阅问题跟踪器文档

此工件没有版本说明。

版本 1.0

版本 1.0.0-alpha06

2025 年 8 月 13 日

发布了 androidx.navigationevent:navigationevent-*:1.0.0-alpha06。版本 1.0.0-alpha06 中包含这些提交内容

新功能

被动监听器 API

现在,您可以从任何导航宿主传递自定义情境信息,并从界面中的任何位置被动监听手势状态变化。这样,系统便可为预测性返回和其他手势驱动的导航启用情境感知动画。

此功能包含两部分:

  1. 提供信息 - 使用 NavigationEventInfo 携带自定义数据。
  2. 消耗状态 - 使用 dispatcher.state (NavigationEventState) 观察手势进度和上下文。
  • NavigationEventCallback 现在公开了 setInfo(currentInfo, previousInfo) 方法,以便通过一次调用设置手势上下文(I1d5e7b/424470518)。
  • NavigationEventHandler 添加了一个接受 currentInfopreviousInfo 的新重载,使其成为在 Compose 应用中提供上下文的主要 API(I6ecd3b/424470518)。

示例:

  data class MyScreenInfo(val screenName: String) : NavigationEventInfo

  NavigationEventHandler(
      enabled = true,
      currentInfo = MyScreenInfo("Details Screen"),
      previousInfo = MyScreenInfo("Home Screen")
  ) { /* Handle back completion */ }
  • NavigationEventDispatcher 现在会公开 dispatcher.statedispatcher.getState<T>()If7faeIa90cab/424470518)。借助这些基于 StateFlow 的 API,任何界面都可以观察手势进度和情境数据,而无需直接处理事件。

示例:

  val gestureState by LocalNavigationEventDispatcherOwner.current!!
      .navigationEventDispatcher
      .state
      .collectAsState()

  val progress = gestureState.progress // Returns latestEvent.progress or 0F

  when (val state = gestureState) {
      is InProgress -> {
          val toScreen = state.currentInfo as MyScreenInfo
          val fromScreen = state.previousInfo as MyScreenInfo
          println("Navigating from ${fromScreen.screenName} to ${toScreen.screenName}")
      }
      is Idle -> { /* Idle state */ }
  }
  • NavigationEventState (I7b196) 添加了 progress 属性,该属性在进行中时返回 latestEvent.progress,否则返回 0F

    val progress = state.progress
    
  • 添加了 NavigationEventDispatcherOwner 可组合项,用于以分层方式创建、关联和处置 NavigationEventDispatcher 实例。支持动态控制调度程序的启用状态和自动清理。

    @Composable
    fun Sample() {
        NavigationEventDispatcherOwner(enabled = true) {
            val localDispatcherOwner = LocalNavigationEventDispatcherOwner.current
        }
    }
    

API 变更

  • isPassthrough 参数已从 NavigationEventCallback 中移除。(I99028b/424470518
  • NavigationEventState 构造函数现在是内部函数。对于测试,请通过 DirectNavigationEventInputHandler 更新状态(默认为 Idle)。调用 handleOnStartedhandleOnProgressed 可将状态设置为 InProgress,调用 handleOnCompletedhandleOnCancelled 可将状态返回到 Idle。如需更新 NavigationEventInfo,请使用 NavigationEventCallback.setInfo。(I93dcab/424470518
  • NavigationEvent 添加了默认参数,以便更轻松地进行实例化并简化测试,该函数应取代 TestNavigationEvent。(I5dc49I232f4
  • 添加了 TestNavigationEventCallback,用于测试具有特定当前/之前状态的导航事件。(Idd22eb/424470518
  • NavigationEventInputHandler 已更改为抽象类,以替换之前的 AbstractNavigationEventInputHandler,并在 DirectNavigationEventInputHandler 中实现(Iadde5Ifed40I3897cb/432616296b/435416924
  • NavigationEventInputHandler 中的 send* 函数已将其前缀重命名为 handle*。(Iffcaf)
  • OnBackInvokedInputHandler 现在扩展了新添加的 abstract NavigationInputHandler。(Ib45aa)
  • 更改了 NavigationEventDispatcherOwner,要求使用父调度程序,您必须明确传递 null 才能创建根调度程序。(Ia6f64b/431534103

bug 修复

  • 通过避免在 NavigationEventDispatcher.dispose() 中复制集合来提高效率。(I4ab09)
  • 修复了 NavigationEventHandler 未正确响应其启用状态变化的问题。(Ia5268I19becI5be5cb/431534103

Google 文档更新

  • 扩展了 NavigationEvent 的 KDoc,以阐明其作为统一事件封装容器的角色,并详细说明了不同导航类型(手势、点击)的属性行为。(I91e8d)
  • 更新了有关系统返回处理 Compose API(BackHandlerPredictiveBackHandlerNavigationEventHandler)的文档,以明确说明与回调顺序相关的行为。(I7ab94,)

依赖项更新

  • NavigationEvent 现在依赖于 Compose Runtime 1.9.0-beta03,这使得 navigationevent-compose 制品能够支持所有 KMP 目标。(Ia1b87)

版本 1.0.0-alpha05

2025 年 7 月 30 日

发布了 androidx.navigationevent:navigationevent-*:1.0.0-alpha05。版本 1.0.0-alpha05 中包含这些提交内容

父子层次结构支持

NavigationEventDispatcher 现在可以有父调度器和子调度器,从而形成分层树结构。这样一来,导航事件就可以通过链式调度程序反映界面结构层次结构,从而在复杂的 Compose 界面组件中更灵活地传播和管理。(I194ac)

  // Create a parent dispatcher that will manage navigation events at a higher level.
  val parentDispatcher = NavigationEventDispatcher()

  // Create a child dispatcher linked to the parent, forming a hierarchy.
  val childDispatcher = NavigationEventDispatcher(parentDispatcher)

分层 isEnabled 属性可实现对调度程序的自上而下的控制。当调度器上的 isEnabled 设置为 false 时,它会自动停用其所有后代调度器。此功能可高效地关闭导航事件系统的整个分支。(I9e985)

  // Disabling the child dispatcher disables all its callbacks and any of its children recursively.
  childDispatcher.isEnabled = false

此外,NavigationEventCallback 上的 isEnabled 属性现在会考虑其关联的调度器的启用状态。这意味着,只有当回调本身及其调度程序(包括其祖先)都处于启用状态时,回调才会被视为已启用,从而确保对回调激活进行一致的分层控制。(I1799a)

  // Create a test callback and add it to the child dispatcher.
  val callback1 = TestNavigationEventCallback(isEnabled = true)
  childDispatcher.addCallback(callback1)

  // Since the childDispatcher is disabled, the callback is effectively disabled as well.
  assertThat(callback1.isEnabled).isFalse()

引入了新的 dispose() 方法,用于正确清理调度程序及其子级。调用 dispose() 会停止监听器以防止内存泄漏,以递归方式处置所有子调度器,移除注册到调度器的所有回调,并将其从父级取消关联。这样可确保在不再需要调度程序时正确释放资源。(I9e985)

  // Dispose the child dispatcher to clean up resources.
  childDispatcher.dispose()

如果对已处置的调度程序调用任何公共方法,系统会立即抛出 IllegalStateException。这可以防止出现无提示的失败,并帮助开发者在开发期间发现不当使用情况。(Ic2dc3)

  val callback2 = TestNavigationEventCallback()

  // Attempting to use a disposed dispatcher will throw an exception.
  assertThrows<IllegalStateException> {
      childDispatcher.addCallback(callback2)
  }

注意:我们将在 aosp/3692572 中引入一个新的 NavigationEventDispatcherOwner 可组合项,用于自动管理 Compose 界面中的子调度程序。不过,此变更未纳入当前版本,计划在下一个版本中纳入。

导航测试库

  • 添加了 navigationevent-testing 模块,以便为 navigationevent 库提供专用测试实用程序。(0e50b6)
  • 添加了用于测试的 TestNavigationEventCallback 伪实用程序类。它会记录回调方法调用并存储收到的 NavigationEvent 项,以支持验证。(4a0246)
  • 添加了 TestNavigationEvent 假实用程序函数,用于创建具有默认值的 NavigationEvent 实例,从而简化导航事件处理的单元测试。(3b63f5)
  • 添加了用于测试的 TestNavigationEventDispatcherOwner 伪实用程序类。它会跟踪回退和启用状态更改事件计数,以支持在测试中进行互动验证。(c8753e)

API 变更

  • NavigationEventInputHandlerandroidMain 移至 commonMain,以便在 KMP 通用代码中使用。添加了用于调度事件的新 public send* 方法。将 NavigationEventDispatcher 上派发函数的 public 更改为 internal;用户现在必须使用 NavigationEventInputHandler 来发送事件。(Ia7114)
  • 已将 NavigationInputHandler 重命名为 OnBackInvokedInputHandler。(I63405)

bug 修复

  • 重构了 NavigationEventDispatcher,通过避免中间列表分配和提高回调调度性能来减少开销。(I82702I1a9d9
  • NavigationEvent 中的 touchXtouchYprogress 字段添加了 @FloatRange 注释,以在编译时强制执行有效的值范围并提高 API 安全性。(Iac0ec)

版本 1.0.0-alpha04

2025 年 7 月 2 日

发布了 androidx.navigationevent:navigationevent-*:1.0.0-alpha04。版本 1.0.0-alpha04 中包含这些提交内容

bug 修复

  • 使用 implementedInJetBrainsForknavigationevent-compose 添加到 commonStubs 目标,以符合 Compose 惯例。JetBrains 提出的更改请求。(f60c79)
  • 修复了将 Compose 编译器插件应用于 Kotlin/Native 的问题,以确保正确生成桩。对公开 API 或行为没有影响。(1890c9)

版本 1.0.0-alpha03

2025 年 6 月 18 日

发布了 androidx.navigationevent:navigationevent-*:1.0.0-alpha03。版本 1.0.0-alpha03 中包含这些提交内容

新功能

  • 引入了新的 navigationevent-compose 模块,以支持 navigationevent 库中的 Jetpack Compose 功能。(980d78)
  • NavigationEvent Compose 添加了新的 LocalNavigationEventDispatcherOwner 本地组合。它会返回可为 null 的值,以更好地确定其在当前组合中是否可用。现在,如果未找到底层所有者,NavigationEventHandler 会抛出错误。(62ffda)
  • NavigationEvent Compose 添加了一个新的 NavigationEventHandler 可组合项来处理(预测性返回手势)事件。它提供了一个 Flow,其中包含您提供的挂起 lambda 中必须收集的 NavigationEvent 对象 c42ba6
NavigationEventHandler { progress: Flow<NavigationEvent> ->
  // This block is executed when the back gesture begins.
  try {
    progress.collect { backEvent ->
      // Handle gesture progress updates here.
    }
    // This block is executed if the gesture completes successfully.
  } catch (e: CancellationException) {
    // This block is executed if the gesture is cancelled
    throw e
  } finally {
    // This block is executed either the gesture is completed or cancelled
  }
}

API 变更

  • 现在,每个 NavigationEventCallback 一次只能注册一个 NavigationEventDispatcher;如果将其添加到多个调度程序,则会抛出 IllegalStateException。请注意,此行为与允许使用多个调度程序的 OnBackPressedDispatcher 不同。(e82c19)
  • isPassThrough 设为 val,以防止在导航期间发生突变,从而避免破坏 NavigationEvent 的调度。(I0b287)

版本 1.0.0-alpha02

2025 年 6 月 4 日

发布了 androidx.navigationevent:navigationevent-*:1.0.0-alpha02。版本 1.0.0-alpha02 中包含这些提交内容

API 变更

  • NavigationEventDispatcher 的次构造函数替换为具有默认实参的次构造函数。(I716a0)
  • NavigationEventCallback 中移除了优先级属性。请改为将优先级传递给 NavigationEventDispatcher.addCallback()。(I13cae)

bug 修复

  • 修复了在调用 NavigationEventCallback.remove() 时可能因同时修改可关闭对象的内部列表而发生的 ConcurrentModificationException。(b/420919815)

版本 1.0.0-alpha01

2025 年 5 月 20 日

发布了 androidx.navigationevent:navigationevent-*:1.0.0-alpha01。版本 1.0.0-alpha01 中包含这些提交内容

新功能

  • androidx.navigationevent 库提供了一个 KMP 优先的 API,用于处理系统返回以及预测性返回NavigationEventDispatcher 用作注册一个或多个 NavigationEventCallback 实例以接收系统返回事件的通用 API。
  • 此层位于 androidx.activity 中之前发布的 API 之下,旨在成为一种更灵活的替代方案,用于在更高级别的组件中使用 Activity API 或直接使用 Android 框架 OnBackInvokedDispatcher API。androidx.activity API 已在 Navigation Event API 的基础上重写,作为 Activity 1.12.0-alpha01 的一部分。