androidx.navigationevent.compose

Objects

LocalNavigationEventDispatcherOwner

The CompositionLocal containing the current NavigationEventDispatcher.

Cmn

Top-level functions summary

Unit
@Composable
NavigationEventDispatcherOwner(
    enabled: Boolean,
    parent: NavigationEventDispatcherOwner?,
    content: @Composable () -> Unit
)

Creates a new navigation scope by providing a NavigationEventDispatcher to descendant composables.

Cmn
Unit
@Composable
NavigationEventHandler(
    enabled: Boolean,
    onEvent: suspend (progress: Flow<NavigationEvent>) -> Unit
)

Handles predictive back navigation gestures.

Cmn
Unit
@Composable
<T : NavigationEventInfo> NavigationEventHandler(
    currentInfo: T,
    previousInfo: T?,
    enabled: Boolean,
    onEvent: suspend (progress: Flow<NavigationEvent>) -> Unit
)

Handles predictive back navigation gestures.

Cmn

Top-level functions

@Composable
fun NavigationEventDispatcherOwner(
    enabled: Boolean = true,
    parent: NavigationEventDispatcherOwner? = checkNotNull(LocalNavigationEventDispatcherOwner.current) { "No NavigationEventDispatcherOwner provided in LocalNavigationEventDispatcherOwner. " + "If you intended to create a root dispatcher, explicitly pass null as the parent." },
    content: @Composable () -> Unit
): Unit

Creates a new navigation scope by providing a NavigationEventDispatcher to descendant composables.

This composable creates a dispatcher that links to any parent dispatcher found in the composition, forming a parent-child relationship. If no parent exists, it automatically becomes a new root dispatcher, this is the top-most parent in a hierarchy. This is useful for isolating navigation handling within specific UI sections, such as a self-contained feature screen or tab.

The dispatcher's lifecycle is automatically managed. It is created only once and automatically disposed of when the composable leaves the composition, preventing memory leaks.

When used to create a root dispatcher, you must use a NavigationEventInputHandler to send it events. Otherwise, the dispatcher will be detached and will not receive events.

Null parent: If parent is EXPLICITLY null, this creates a root dispatcher that runs independently. By default, it requires a parent from the LocalNavigationEventDispatcherOwner and will throw an IllegalStateException if one is not present.

Parameters
enabled: Boolean = true

A lambda to dynamically control if the dispatcher is active. When false, this dispatcher and any of its children will ignore navigation events. Defaults to true.

parent: NavigationEventDispatcherOwner? = checkNotNull(LocalNavigationEventDispatcherOwner.current) { "No NavigationEventDispatcherOwner provided in LocalNavigationEventDispatcherOwner. " + "If you intended to create a root dispatcher, explicitly pass null as the parent." }

The NavigationEventDispatcherOwner to use as the parent, or null if it is a root. Defaults to the owner from LocalNavigationEventDispatcherOwner.

content: @Composable () -> Unit

The child composable content that will receive the new dispatcher.

@Composable
fun NavigationEventHandler(
    enabled: Boolean = true,
    onEvent: suspend (progress: Flow<NavigationEvent>) -> Unit
): Unit

Handles predictive back navigation gestures.

This effect registers a callback to receive updates on the progress of system back gestures as a Flow of NavigationEvent.

The onEvent lambda should be structured to handle the start, progress, completion, and cancellation of the gesture:

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.
}
}

Precedence

When multiple NavigationEventHandler are present in the composition, the one that is composed

  • last among all enabled handlers will be invoked.

Usage

It is important to call this composable unconditionally. Use the enabled parameter to control whether the handler is active. This is preferable to conditionally calling NavigationEventHandler (e.g., inside an if block), as conditional calls can change the order of composition, leading to unpredictable behavior where different handlers are invoked after recomposition.

Timing Consideration

There are cases where a predictive back gesture may be dispatched within a rendering frame before the enabled flag is updated, which can cause unexpected behavior (see b/375343407, b/384186542). For example, if enabled is set to false, a gesture initiated in the same frame may still trigger this handler because the system sees the stale true value.

Parameters
enabled: Boolean = true

Controls whether this handler is active. Important: Due to the timing issue described above, a gesture starting immediately after enabled is set to false may still trigger this handler.

onEvent: suspend (progress: Flow<NavigationEvent>) -> Unit

The lambda that receives the flow of back gesture events when a gesture begins. You must collect the flow within this lambda.

@Composable
fun <T : NavigationEventInfo> NavigationEventHandler(
    currentInfo: T,
    previousInfo: T?,
    enabled: Boolean = true,
    onEvent: suspend (progress: Flow<NavigationEvent>) -> Unit
): Unit

Handles predictive back navigation gestures.

This overload allows associating specific NavigationEventInfo with the current state (from which the user is navigating) and the previous state (to which the user may return). This is useful for creating animations that are specific to the content being displayed.

This effect registers a callback to receive updates on the progress of system back gestures as a Flow of NavigationEvent.

The onEvent lambda should be structured to handle the start, progress, completion, and cancellation of the gesture:

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.
}
}

Precedence

When multiple NavigationEventHandler are present in the composition, the one that is composed

  • last among all enabled handlers will be invoked.

Usage

It is important to call this composable unconditionally. Use the enabled parameter to control whether the handler is active. This is preferable to conditionally calling NavigationEventHandler (e.g., inside an if block), as conditional calls can change the order of composition, leading to unpredictable behavior where different handlers are invoked after recomposition.

Timing Consideration

There are cases where a predictive back gesture may be dispatched within a rendering frame before the enabled flag is updated, which can cause unexpected behavior (see b/375343407, b/384186542). For example, if enabled is set to false, a gesture initiated in the same frame may still trigger this handler because the system sees the stale true value.

Parameters
<T : NavigationEventInfo>

The type of the navigation information.

currentInfo: T

An object containing information about the current destination.

previousInfo: T?

An object containing information about the destination the user is navigating back to. Can be null if the information is not available.

enabled: Boolean = true

Controls whether this handler is active. Important: Due to the timing issue described above, a gesture starting immediately after enabled is set to false may still trigger this handler.

onEvent: suspend (progress: Flow<NavigationEvent>) -> Unit

The lambda that receives the flow of back gesture events when a gesture begins. You must collect the flow within this lambda.