The Developer Preview for Android 11 is now available; test it out and share your feedback.

Ambient

@Immutable sealed class Ambient<T>
kotlin.Any
   ↳ androidx.compose.Ambient

Compose passes data through the composition tree explicitly through means of parameters to composable functions. This is often times the simplest and best way to have data flow through the tree.

Sometimes this model can be cumbersome or break down for data that is needed by lots of components, or when components need to pass data between one another but keep that implementation detail private. For these cases, Ambients can be used as an implicit way to have data flow through a composition.

Ambients by their nature are hierarchical. They make sense when the value of the ambient needs to be scoped to a particular sub-hierarchy of the composition.

One must create an Ambient instance, which can be referenced by the consumers statically. Ambient instances themselves hold no data, and can be thought of as a type-safe identifier for the data being passed down a tree. Ambient factory functions takes a single parameter, a factory to create a default value in cases where an ambient is used without a Provider. If this is a situation you would rather not handle, you can throw an error in this factory

import androidx.compose.ambientOf

val ActiveUser = ambientOf<User> { error("No active user found!") }
Somewhere up the tree, a Providers component can be used, which provides a value for theambient. This would often be at the "root" of a tree, but could be anywhere, and can also beused in multiple places to override the provided value for a sub-tree.
import androidx.compose.Providers

@Composable
fun App(user: User) {
    Providers(ActiveUser provides user) {
        SomeScreen()
    }
}
Intermediate components do not need to know about the ambient value, and can have zerodependencies on it. For example, SomeScreen might look like this:

@Composable
fun SomeScreen() {
    UserPhoto()
}
Finally, a component that wishes to consume the ambient value can use the currentproperty of the ambient key which returns the current value of the ambient, and subscribes thecomponent to changes of it.

@Composable
fun UserPhoto() {
    val user = ActiveUser.current
    ProfileIcon(src = user.profilePhotoUrl)
}

Summary

Inherited extension functions

From androidx.compose
operator T

IMPORTANT: This global operator is TEMPORARY, and should be removed whenever an answer for contextual composers is reached.

Properties

T

Return the value provided by the nearest Providers component that invokes, directly or indirectly, the composable function that uses this property.

Properties

current

@Composable inline val current: T

Return the value provided by the nearest Providers component that invokes, directly or indirectly, the composable function that uses this property.


@Composable
fun UserPhoto() {
    val user = ActiveUser.current
    ProfileIcon(src = user.profilePhotoUrl)
}