Ambient

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. The Ambient constructor 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


val ActiveUser = Ambient.of<User> { error("No active user found!") }
Somewhere up the tree, a Provider component can be used, which has a required valueparameter. 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.

@Composable
fun App(user: User) {
    ActiveUser.Provider(value = 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 correspondingambient effect, which returns the current value of the ambient, and subscribes the componentto changes of it.
import androidx.compose.ambient

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

Summary

Public methods

Unit
Provider(value: T, children: () -> Unit)

The Provider component allows one to provide an ambient value to a section of the tree during composition.

Boolean
equals(other: Any?)

Companion functions

Ambient<T>
of(defaultFactory: () -> T = null)

Creates an ambient to be used during composition.

Public methods

Provider

@Composable fun Provider(
    value: T,
    children: () -> Unit
): Unit

The Provider component allows one to provide an ambient value to a section of the tree during composition. All consumers of the ambient that are underneath this component will receive the value provided here. Consuming components are guaranteed to be invalidated and recomposed when this value changes.

Parameters
value: T The current value of the ambient.
children: () -> Unit Everything composed inside this block will get value when consuming this ambient

See Also

equals

fun equals(other: Any?): Boolean

Companion functions

of

fun <T> of(defaultFactory: () -> T = null): Ambient<T>

Creates an ambient to be used during composition.

Parameters
defaultFactory: () -> T = null A lambda to run to create a default value of this ambient for when the ambient is consumed in a composition and there is no provider above the point of consumption. If no factory is provided, and T is not a nullable type, an exception will be thrown. This factory will not be executed more than once.