androidx.compose.runtime

In this page, you'll find documentation for types, properties, and functions available in the androidx.compose.runtime package. For example:

If you're looking for guidance instead, check out the following Compose guides:

Interfaces

Applier

An Applier is responsible for applying the tree-based operations that get emitted during a composition.

Cmn
ComposeNodeLifecycleCallback

Observes lifecycle of the node emitted with ReusableComposeNode or ComposeNode inside ReusableContentHost and ReusableContent.

Cmn
Composer

Composer is the interface that is targeted by the Compose Kotlin compiler plugin and used by code generation helpers.

Cmn
Composition

A composition object is usually constructed for you, and returned from an API that is used to initially compose a UI.

Cmn
CompositionLocalMap

A read-only, immutable snapshot of the CompositionLocals that are set at a specific position in the composition hierarchy.

Cmn
CompositionServiceKey

A key to locate a service using the CompositionServices interface optionally implemented by implementations of Composition.

Cmn
CompositionServices

Allows finding composition services from the runtime.

Cmn
CompositionTracer

Internal tracing API.

Cmn
ControlledComposition

A controlled composition is a Composition that can be directly controlled by the caller.

Cmn
DisposableEffectResult
Cmn
DoubleState

A value holder where reads to the doubleValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
FloatState

A value holder where reads to the floatValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
IntState

A value holder where reads to the intValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
LongState

A value holder where reads to the longValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
MonotonicFrameClock

Provides a time source for display frames and the ability to perform an action on the next frame.

Cmn
MutableDoubleState

A value holder where reads to the doubleValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
MutableFloatState

A value holder where reads to the floatValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
MutableIntState

A value holder where reads to the intValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
MutableLongState

A value holder where reads to the longValue property during the execution of a Composable function cause the current RecomposeScope to subscribe to changes of that value.

Cmn
MutableState

A mutable value holder where reads to the value property during the execution of a Composable function, the current RecomposeScope will be subscribed to changes of that value.

Cmn
ProduceStateScope

Receiver scope for use with produceState.

Cmn
RecomposeScope

Represents a recomposable scope or section of the composition hierarchy.

Cmn
RecomposerInfo

Read-only information about a Recomposer.

Cmn
RememberObserver

Objects implementing this interface are notified when they are initially used in a composition and when they are no longer being used.

Cmn
ReusableComposition

A ReusableComposition is a Composition that can be reused for different composable content.

Cmn
ScopeUpdateScope

Internal compose compiler plugin API that is used to update the function the composer will call to recompose a recomposition scope.

Cmn
SnapshotMutationPolicy

A policy to control how the result of mutableStateOf report and merge changes to the state object.

Cmn
State

A value holder where reads to the value property during the execution of a Composable function, the current RecomposeScope will be subscribed to changes of that value.

Cmn

Classes

AbstractApplier

An abstract Applier implementation.

Cmn
BroadcastFrameClock

A simple frame clock.

Cmn
CompositionContext

A CompositionContext is an opaque type that is used to logically "link" two compositions together.

Cmn
CompositionLocal

Compose passes data through the composition tree explicitly through means of parameters to composable functions.

Cmn
CompositionLocalContext

Stores CompositionLocal's and their values.

Cmn
DisposableEffectScope

Receiver scope for DisposableEffect that offers the onDispose clause that should be the last statement in any call to DisposableEffect.

Cmn
MovableContent

A Compose compiler plugin API.

Cmn
MovableContentState

A Compose compiler plugin API.

Cmn
MovableContentStateReference

A Compose compiler plugin API.

Cmn
PausableMonotonicFrameClock

A MonotonicFrameClock wrapper that can be paused and resumed.

Cmn
ProvidableCompositionLocal

A ProvidableCompositionLocal can be used in CompositionLocalProvider to provide values.

Cmn
ProvidedValue

An instance to hold a value provided by CompositionLocalProvider and is created by the ProvidableCompositionLocal.provides infixed operator.

Cmn
Recomposer

The scheduler for performing recomposition and applying updates to one or more Compositions.

Cmn
SkippableUpdater
Cmn
Updater

A helper receiver scope class used by ComposeNode to help write code to initialized and update a node.

Cmn

Objects

Annotations

CheckResult
Cmn
android
Composable

Composable functions are the fundamental building blocks of an application built with Compose.

Cmn
ComposableInferredTarget

An annotation generated by the compose compiler plugin.

Cmn
ComposableOpenTarget

The Composable declares that it doesn't expect a particular applier.

Cmn
ComposableTarget

The Composable function is declared to expect an applier with the name applier.

Cmn
ComposableTargetMarker

This annotation is used to mark an annotation as being equivalent using ComposableTarget with the fully qualified name of the marked annotation as the applier value.

Cmn
ComposeCompilerApi
Cmn
DisallowComposableCalls

This will prevent composable calls from happening inside of the function that it applies to.

Cmn
DontMemoize

Mark a lambda in composition to opt out of auto-memoization.

Cmn
ExperimentalComposeApi
Cmn
ExperimentalComposeRuntimeApi
Cmn
ExplicitGroupsComposable

This annotation can be applied to Composable functions so that no groups will be generated in the body of the function it annotates.

Cmn
Immutable

Immutable can be used to mark class as producing immutable instances.

Cmn
InternalComposeApi
Cmn
InternalComposeTracingApi
Cmn
NoLiveLiterals

This annotation is used to indicate to the Compose Compiler to not attempt to generate live literals inside the scope of the declaration it is applied to, even when the live literals code generation is turned on.

Cmn
NonRestartableComposable

This annotation can be applied to Composable functions in order to prevent code from being generated which allow this function's execution to be skipped or restarted.

Cmn
NonSkippableComposable

This annotation can be applied to Composable functions in order to prevent code from being generated which allow this function's execution to be skipped.

Cmn
ReadOnlyComposable

This annotation can be applied to Composable functions so that no group will be generated around the body of the function it annotates.

Cmn
Stable

Stable is used to communicate some guarantees to the compose compiler about how a certain type or function will behave.

Cmn
StableMarker

StableMarker marks an annotation as indicating a type is stable.

Cmn
TestOnly
Cmn

Enums

Recomposer.State

Valid operational states of a Recomposer.

Cmn

Top-level functions summary

inline Unit
@Composable
<T : Any, E : Applier<*>> ComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit
)

Emits a node into the composition of type T.

Cmn
inline Unit
@Composable
<T : Any?, E : Applier<*>> ComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    content: @Composable () -> Unit
)

Emits a node into the composition of type T.

Cmn
inline Unit
@Composable
@ExplicitGroupsComposable
<T : Any?, E : Applier<*>> ComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    noinline skippableUpdate: @Composable SkippableUpdater<T>.() -> Unit,
    content: @Composable () -> Unit
)

Emits a node into the composition of type T.

Cmn
Composition
Composition(applier: Applier<*>, parent: CompositionContext)

This method is the way to initiate a composition.

Cmn
Composition
@ExperimentalComposeApi
Composition(
    applier: Applier<*>,
    parent: CompositionContext,
    recomposeCoroutineContext: CoroutineContext
)

Create a Composition using applier to manage the composition, as a child of parent.

Cmn
Unit
@Composable
CompositionLocalProvider(
    context: CompositionLocalContext,
    content: @Composable () -> Unit
)

CompositionLocalProvider binds values to CompositionLocal's, provided by context.

Cmn
Unit

CompositionLocalProvider binds value to ProvidableCompositionLocal key.

Cmn
Unit
@Composable
@NonSkippableComposable
CompositionLocalProvider(
    vararg values: ProvidedValue<*>,
    content: @Composable () -> Unit
)

CompositionLocalProvider binds values to ProvidableCompositionLocal keys.

Cmn
ControlledComposition

This method is a way to initiate a composition.

Cmn
ControlledComposition
@TestOnly
@ExperimentalComposeApi
ControlledComposition(
    applier: Applier<*>,
    parent: CompositionContext,
    recomposeCoroutineContext: CoroutineContext
)
Cmn
Unit

This function is deprecated. DisposableEffect must provide one or more 'key' parameters that define the identity of the DisposableEffect and determine when its previous effect should be disposed and a new effect started for the new key.

Cmn
Unit

A side effect of composition that must run for any new unique value of key1 and must be reversed or cleaned up if key1 changes or if the DisposableEffect leaves the composition.

Cmn
Unit

A side effect of composition that must run for any new unique value of keys and must be reversed or cleaned up if any keys change or if the DisposableEffect leaves the composition.

Cmn
Unit

A side effect of composition that must run for any new unique value of key1 or key2 and must be reversed or cleaned up if key1 or key2 changes, or if the DisposableEffect leaves the composition.

Cmn
Unit
@Composable
@NonRestartableComposable
DisposableEffect(
    key1: Any?,
    key2: Any?,
    key3: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult
)

A side effect of composition that must run for any new unique value of key1, key2 or key3 and must be reversed or cleaned up if key1, key2 or key3 changes, or if the DisposableEffect leaves the composition.

Cmn
Unit

This function is deprecated. LaunchedEffect must provide one or more 'key' parameters that define the identity of the LaunchedEffect and determine when its previous effect coroutine should be cancelled and a new effect launched for the new key.

Cmn
Unit

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext.

Cmn
Unit
@Composable
@NonRestartableComposable
LaunchedEffect(vararg keys: Any?, block: suspend CoroutineScope.() -> Unit)

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext.

Cmn
Unit
@Composable
@NonRestartableComposable
LaunchedEffect(key1: Any?, key2: Any?, block: suspend CoroutineScope.() -> Unit)

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext.

Cmn
Unit
@Composable
@NonRestartableComposable
LaunchedEffect(key1: Any?, key2: Any?, key3: Any?, block: suspend CoroutineScope.() -> Unit)

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext.

Cmn
inline Unit
@Composable
<T : Any, E : Applier<*>> ReusableComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit
)

Emits a recyclable node into the composition of type T.

Cmn
inline Unit
@Composable
<T : Any?, E : Applier<*>> ReusableComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    content: @Composable () -> Unit
)

Emits a recyclable node into the composition of type T.

Cmn
inline Unit
@Composable
@ExplicitGroupsComposable
<T : Any?, E : Applier<*>> ReusableComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    noinline skippableUpdate: @Composable SkippableUpdater<T>.() -> Unit,
    content: @Composable () -> Unit
)

Emits a recyclable node into the composition of type T.

Cmn
ReusableComposition

This method is the way to initiate a reusable composition.

Cmn
inline Unit
@Composable
ReusableContent(key: Any?, content: @Composable () -> Unit)

A utility function to mark a composition as supporting recycling.

Cmn
inline Unit
@Composable
@ExplicitGroupsComposable
ReusableContentHost(
    active: Boolean,
    crossinline content: @Composable () -> Unit
)

An optional utility function used when hosting ReusableContent.

Cmn
Unit

Schedule effect to run when the current composition completes successfully and applies changes.

Cmn
ProvidableCompositionLocal<T>
<T : Any?> compositionLocalOf(
    policy: SnapshotMutationPolicy<T>,
    defaultFactory: () -> T
)

Create a CompositionLocal key that can be provided using CompositionLocalProvider.

Cmn
State<T>
@StateFactoryMarker
<T : Any?> derivedStateOf(calculation: () -> T)

Creates a State object whose State.value is the result of calculation.

Cmn
State<T>
@StateFactoryMarker
<T : Any?> derivedStateOf(
    policy: SnapshotMutationPolicy<T>,
    calculation: () -> T
)

Creates a State object whose State.value is the result of calculation.

Cmn
Boolean

Internal tracing API.

Cmn
inline T
@Composable
<T : Any?> key(vararg keys: Any?, block: @Composable () -> T)

key is a utility composable that is used to "group" or "key" a block of execution inside of a composition.

Cmn
@Composable () -> Unit
movableContentOf(content: @Composable () -> Unit)

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable (P) -> Unit
<P : Any?> movableContentOf(content: @Composable (P) -> Unit)

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable (P1, P2) -> Unit
<P1 : Any?, P2 : Any?> movableContentOf(content: @Composable (P1, P2) -> Unit)

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable (P1, P2, P3) -> Unit
<P1 : Any?, P2 : Any?, P3 : Any?> movableContentOf(
    content: @Composable (P1, P2, P3) -> Unit
)

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable (P1, P2, P3, P4) -> Unit
<P1 : Any?, P2 : Any?, P3 : Any?, P4 : Any?> movableContentOf(
    content: @Composable (P1, P2, P3, P4) -> Unit
)

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable R.() -> Unit
<R : Any?> movableContentWithReceiverOf(content: @Composable R.() -> Unit)

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable R.(P) -> Unit
<R : Any?, P : Any?> movableContentWithReceiverOf(content: @Composable R.(P) -> Unit)

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable R.(P1, P2) -> Unit
<R : Any?, P1 : Any?, P2 : Any?> movableContentWithReceiverOf(
    content: @Composable R.(P1, P2) -> Unit
)

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
@Composable R.(P1, P2, P3) -> Unit
<R : Any?, P1 : Any?, P2 : Any?, P3 : Any?> movableContentWithReceiverOf(
    content: @Composable R.(P1, P2, P3) -> Unit
)

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Cmn
MutableDoubleState

Return a new MutableDoubleState initialized with the passed in value

Cmn
MutableFloatState

Return a new MutableFloatState initialized with the passed in value

Cmn
MutableIntState

Return a new MutableIntState initialized with the passed in value

Cmn
MutableLongState

Return a new MutableLongState initialized with the passed in value

Cmn
SnapshotStateList<T>

Create a instance of MutableList that is observable and can be snapshot.

Cmn
SnapshotStateList<T>
@StateFactoryMarker
<T : Any?> mutableStateListOf(vararg elements: T)

Create an instance of MutableList that is observable and can be snapshot.

Cmn
SnapshotStateMap<K, V>

Create a instance of MutableMap that is observable and can be snapshot.

Cmn
SnapshotStateMap<K, V>
@StateFactoryMarker
<K : Any?, V : Any?> mutableStateMapOf(vararg pairs: Pair<K, V>)

Create a instance of MutableMap that is observable and can be snapshot.

Cmn
MutableState<T>

Return a new MutableState initialized with the passed in value

Cmn
SnapshotMutationPolicy<T>

A policy never treat values of a MutableState as equivalent.

Cmn
State<T>
@Composable
<T : Any?> produceState(initialValue: T, producer: suspend ProduceStateScope<T>.() -> Unit)

Return an observable snapshot State that produces values over time without a defined data source.

Cmn
State<T>
@Composable
<T : Any?> produceState(initialValue: T, key1: Any?, producer: suspend ProduceStateScope<T>.() -> Unit)

Return an observable snapshot State that produces values over time from key1.

Cmn
State<T>
@Composable
<T : Any?> produceState(
    initialValue: T,
    vararg keys: Any?,
    producer: suspend ProduceStateScope<T>.() -> Unit
)

Return an observable snapshot State that produces values over time from keys.

Cmn
State<T>
@Composable
<T : Any?> produceState(
    initialValue: T,
    key1: Any?,
    key2: Any?,
    producer: suspend ProduceStateScope<T>.() -> Unit
)

Return an observable snapshot State that produces values over time from key1 and key2.

Cmn
State<T>
@Composable
<T : Any?> produceState(
    initialValue: T,
    key1: Any?,
    key2: Any?,
    key3: Any?,
    producer: suspend ProduceStateScope<T>.() -> Unit
)

Return an observable snapshot State that produces values over time from key1, key2 and key3.

Cmn
SnapshotMutationPolicy<T>

A policy to treat values of a MutableState as equivalent if they are referentially (===) equal.

Cmn
inline T
@Composable
<T : Any?> remember(crossinline calculation: @DisallowComposableCalls () -> T)

Remember the value produced by calculation.

Cmn
inline T
@Composable
<T : Any?> remember(
    key1: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
)

Remember the value returned by calculation if key1 compares equal (==) to the value it had in the previous composition, otherwise produce and remember a new value by calling calculation.

Cmn
inline T
@Composable
<T : Any?> remember(
    vararg keys: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
)

Remember the value returned by calculation if all values of keys are equal (==) to the values they had in the previous composition, otherwise produce and remember a new value by calling calculation.

Cmn
inline T
@Composable
<T : Any?> remember(
    key1: Any?,
    key2: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
)

Remember the value returned by calculation if key1 and key2 are equal (==) to the values they had in the previous composition, otherwise produce and remember a new value by calling calculation.

Cmn
inline T
@Composable
<T : Any?> remember(
    key1: Any?,
    key2: Any?,
    key3: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
)

Remember the value returned by calculation if key1, key2 and key3 are equal (==) to values they had in the previous composition, otherwise produce and remember a new value by calling calculation.

Cmn
CompositionContext

An Effect to construct a CompositionContext at the current point of composition.

Cmn
inline CoroutineScope

Return a CoroutineScope bound to this point in the composition using the optional CoroutineContext provided by getContext.

Cmn
State<T>
@Composable
<T : Any?> rememberUpdatedState(newValue: T)

remember a mutableStateOf and update its value to newValue on each recomposition of the rememberUpdatedState call.

Cmn
Flow<T>
<T : Any?> snapshotFlow(block: () -> T)

Create a Flow from observable Snapshot state.

Cmn
Unit
@ComposeCompilerApi
sourceInformation(composer: Composer, sourceInformation: String)

A Compose internal function.

Cmn
Unit

A Compose internal function.

Cmn
Unit
@ComposeCompilerApi
sourceInformationMarkerStart(
    composer: Composer,
    key: Int,
    sourceInformation: String
)

A Compose internal function.

Cmn
ProvidableCompositionLocal<T>
<T : Any?> staticCompositionLocalOf(defaultFactory: () -> T)

Create a CompositionLocal key that can be provided using CompositionLocalProvider.

Cmn
SnapshotMutationPolicy<T>

A policy to treat values of a MutableState as equivalent if they are structurally (==) equal.

Cmn
Unit

Internal tracing API.

Cmn
Unit
@ComposeCompilerApi
traceEventStart(key: Int, dirty1: Int, dirty2: Int, info: String)

Internal tracing API.

Cmn
suspend R
<R : Any?> withFrameMillis(onFrame: (frameTimeMillis: Long) -> R)

Suspends until a new frame is requested, immediately invokes onFrame with the frame time in milliseconds in the calling context of frame dispatch, then resumes with the result from onFrame.

Cmn
suspend R
<R : Any?> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R)

Suspends until a new frame is requested, immediately invokes onFrame with the frame time in nanoseconds in the calling context of frame dispatch, then resumes with the result from onFrame.

Cmn
suspend R
<R : Any?> withRunningRecomposer(block: suspend CoroutineScope.(recomposer: Recomposer) -> R)

Runs block with a new, active Recomposer applying changes in the calling CoroutineContext.

Cmn

Extension functions summary

DoubleState

Converts a State<Double> (as in, a State of boxed Doubles) into a primitive-backed Double.

Cmn
FloatState

Converts a State<Float> (as in, a State of boxed Floats) into a primitive-backed Float.

Cmn
IntState

Converts a State<Int> (as in, a State of boxed Ints) into a primitive-backed IntState.

Cmn
LongState

Converts a State<Long> (as in, a State of boxed Longs) into a primitive-backed LongState.

Cmn
inline T
@ComposeCompilerApi
<T : Any?> Composer.cache(
    invalid: Boolean,
    block: @DisallowComposableCalls () -> T
)

A Compose compiler plugin API.

Cmn
State<T>

Collects values from this StateFlow and represents its latest value via State.

Cmn
State<R>
@Composable
<T : R, R : Any?> Flow<T>.collectAsState(initial: R, context: CoroutineContext)

Collects values from this Flow and represents its latest value via State.

Cmn
inline operator Double
DoubleState.getValue(thisObj: Any?, property: KProperty<*>)

Permits property delegation of vals using by for DoubleState.

Cmn
inline operator Float
FloatState.getValue(thisObj: Any?, property: KProperty<*>)

Permits property delegation of vals using by for FloatState.

Cmn
inline operator Int
IntState.getValue(thisObj: Any?, property: KProperty<*>)

Permits property delegation of vals using by for IntState.

Cmn
inline operator Long
LongState.getValue(thisObj: Any?, property: KProperty<*>)

Permits property delegation of vals using by for LongState.

Cmn
inline operator T
<T : Any?> State<T>.getValue(thisObj: Any?, property: KProperty<*>)

Permits property delegation of vals using by for State.

Cmn
inline operator Unit
MutableDoubleState.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: Double
)

Permits property delegation of vars using by for MutableDoubleState.

Cmn
inline operator Unit
MutableFloatState.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: Float
)

Permits property delegation of vars using by for MutableFloatState.

Cmn
inline operator Unit
MutableIntState.setValue(thisObj: Any?, property: KProperty<*>, value: Int)

Permits property delegation of vars using by for MutableIntState.

Cmn
inline operator Unit
MutableLongState.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: Long
)

Permits property delegation of vars using by for MutableLongState.

Cmn
inline operator Unit
<T : Any?> MutableState<T>.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: T
)

Permits property delegation of vars using by for MutableState.

Cmn
SnapshotStateList<T>

Create an instance of MutableList from a collection that is observable and can be snapshot.

Cmn
SnapshotStateMap<K, V>
<K : Any?, V : Any?> Iterable<Pair<K, V>>.toMutableStateMap()

Create an instance of MutableMap from a collection of pairs that is observable and can be snapshot.

Cmn
suspend inline R
<R : Any?> MonotonicFrameClock.withFrameMillis(
    crossinline onFrame: (frameTimeMillis: Long) -> R
)

Suspends until a new frame is requested, immediately invokes onFrame with the frame time in milliseconds in the calling context of frame dispatch, then resumes with the result from onFrame.

Cmn

Top-level properties summary

MonotonicFrameClock

This property is deprecated. MonotonicFrameClocks are not globally applicable across platforms.

Cmn
android
Composer

TODO(lmr): provide documentation

Cmn
Int

This a hash value used to coordinate map externally stored state to the composition.

Cmn
CompositionLocalContext

Returns the current CompositionLocalContext which contains all CompositionLocal's in the current composition and their values provided by CompositionLocalProvider's.

Cmn
RecomposeScope

Returns an object which can be used to invalidate the current scope at this point in composition.

Cmn

Extension properties summary

MonotonicFrameClock

Returns the MonotonicFrameClock for this CoroutineContext or throws IllegalStateException if one is not present.

Cmn
CoroutineContext

The CoroutineContext that should be used to perform concurrent recompositions of this ControlledComposition when used in an environment supporting concurrent composition.

Cmn

Top-level functions

ComposeNode

@Composable
inline fun <T : Any, E : Applier<*>> ComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit
): Unit

Emits a node into the composition of type T.

This function will throw a runtime exception if E is not a subtype of the applier of the currentComposer.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
noinline factory: () -> T

A function which will create a new instance of T. This function is NOT guaranteed to be called in place.

update: @DisallowComposableCalls Updater<T>.() -> Unit

A function to perform updates on the node. This will run every time emit is executed. This function is called in place and will be inlined.

ComposeNode

@Composable
inline fun <T : Any?, E : Applier<*>> ComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    content: @Composable () -> Unit
): Unit

Emits a node into the composition of type T. Nodes emitted inside of content will become children of the emitted node.

This function will throw a runtime exception if E is not a subtype of the applier of the currentComposer.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
noinline factory: () -> T

A function which will create a new instance of T. This function is NOT guaranteed to be called in place.

update: @DisallowComposableCalls Updater<T>.() -> Unit

A function to perform updates on the node. This will run every time emit is executed. This function is called in place and will be inlined.

content: @Composable () -> Unit

the composable content that will emit the "children" of this node.

ComposeNode

@Composable
@ExplicitGroupsComposable
inline fun <T : Any?, E : Applier<*>> ComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    noinline skippableUpdate: @Composable SkippableUpdater<T>.() -> Unit,
    content: @Composable () -> Unit
): Unit

Emits a node into the composition of type T. Nodes emitted inside of content will become children of the emitted node.

This function will throw a runtime exception if E is not a subtype of the applier of the currentComposer.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
noinline factory: () -> T

A function which will create a new instance of T. This function is NOT guaranteed to be called in place.

update: @DisallowComposableCalls Updater<T>.() -> Unit

A function to perform updates on the node. This will run every time emit is executed. This function is called in place and will be inlined.

noinline skippableUpdate: @Composable SkippableUpdater<T>.() -> Unit

A function to perform updates on the node. Unlike update, this function is Composable and will therefore be skipped unless it has been invalidated by some other mechanism. This can be useful to perform expensive calculations for updating the node where the calculations are likely to have the same inputs over time, so the function's execution can be skipped.

content: @Composable () -> Unit

the composable content that will emit the "children" of this node.

Composition

fun Composition(applier: Applier<*>, parent: CompositionContext): Composition

This method is the way to initiate a composition. parent can be

  • provided to make the composition behave as a sub-composition of the parent. If composition does

  • not have a parent, Recomposer instance should be provided.

It is important to call Composition.dispose when composition is no longer needed in order to release resources.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
applier: Applier<*>

The Applier instance to be used in the composition.

parent: CompositionContext

The parent CompositionContext.

Composition

@ExperimentalComposeApi
fun Composition(
    applier: Applier<*>,
    parent: CompositionContext,
    recomposeCoroutineContext: CoroutineContext
): Composition

Create a Composition using applier to manage the composition, as a child of parent.

When used in a configuration that supports concurrent recomposition, hint to the environment that recomposeCoroutineContext should be used to perform recomposition. Recompositions will be launched into the

CompositionLocalProvider

@Composable
fun CompositionLocalProvider(
    context: CompositionLocalContext,
    content: @Composable () -> Unit
): Unit

CompositionLocalProvider binds values to CompositionLocal's, provided by context. Reading the CompositionLocal using CompositionLocal.current will return the value provided in values stored inside context for all composable functions called directly or indirectly in the content lambda.

import androidx.compose.runtime.CompositionLocalProvider

@Composable
fun App(user: User) {
    CompositionLocalProvider(ActiveUser provides user) {
        SomeScreen()
    }
}

CompositionLocalProvider

@Composable
@NonSkippableComposable
fun CompositionLocalProvider(
    value: ProvidedValue<*>,
    content: @Composable () -> Unit
): Unit

CompositionLocalProvider binds value to ProvidableCompositionLocal key. Reading the CompositionLocal using CompositionLocal.current will return the value provided in CompositionLocalProvider's value parameter for all composable functions called directly or indirectly in the content lambda.

import androidx.compose.runtime.CompositionLocalProvider

@Composable
fun App(user: User) {
    CompositionLocalProvider(ActiveUser provides user) {
        SomeScreen()
    }
}

CompositionLocalProvider

@Composable
@NonSkippableComposable
fun CompositionLocalProvider(
    vararg values: ProvidedValue<*>,
    content: @Composable () -> Unit
): Unit

CompositionLocalProvider binds values to ProvidableCompositionLocal keys. Reading the CompositionLocal using CompositionLocal.current will return the value provided in CompositionLocalProvider's values parameter for all composable functions called directly or indirectly in the content lambda.

import androidx.compose.runtime.CompositionLocalProvider

@Composable
fun App(user: User) {
    CompositionLocalProvider(ActiveUser provides user) {
        SomeScreen()
    }
}

ControlledComposition

@TestOnly
fun ControlledComposition(applier: Applier<*>, parent: CompositionContext): ControlledComposition

This method is a way to initiate a composition. Optionally, a parent can be provided to make the composition behave as a sub-composition of the parent or a Recomposer can be provided.

A controlled composition allows direct control of the composition instead of it being controlled by the Recomposer passed ot the root composition.

It is important to call Composition.dispose this composer is no longer needed in order to release resources.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
applier: Applier<*>

The Applier instance to be used in the composition.

parent: CompositionContext

The parent CompositionContext.

ControlledComposition

@TestOnly
@ExperimentalComposeApi
fun ControlledComposition(
    applier: Applier<*>,
    parent: CompositionContext,
    recomposeCoroutineContext: CoroutineContext
): ControlledComposition

DisposableEffect

@Composable
@NonRestartableComposable
fun DisposableEffect(effect: DisposableEffectScope.() -> DisposableEffectResult): Unit

A side effect of composition that must be reversed or cleaned up if the DisposableEffect leaves the composition.

It is an error to call DisposableEffect without at least one key parameter.

DisposableEffect

@Composable
@NonRestartableComposable
fun DisposableEffect(key1: Any?, effect: DisposableEffectScope.() -> DisposableEffectResult): Unit

A side effect of composition that must run for any new unique value of key1 and must be reversed or cleaned up if key1 changes or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to

  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun UserProfile(userRepository: UserRepository, userRequest: UserDataRequest) {
    var userDataState by remember { mutableStateOf<UserDataState>(UserDataState.Loading) }

    // If either the repository or request change, we must cancel our old data fetch
    // and begin a new data fetch. We will cancel the current data fetch if UserProfile
    // leaves the composition.
    DisposableEffect(userRepository, userRequest) {
        val requestDisposable = userRepository.fetchUserData(
            userRequest,
            onSuccess = { response ->
                userDataState = UserDataState.UserData(response)
            },
            onError = { throwable ->
                userDataState = UserDataState.Error(throwable.message)
            }
        )

        onDispose {
            requestDisposable.dispose()
        }
    }

    // ...
}

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

DisposableEffect

@Composable
@NonRestartableComposable
fun DisposableEffect(vararg keys: Any?, effect: DisposableEffectScope.() -> DisposableEffectResult): Unit

A side effect of composition that must run for any new unique value of keys and must be reversed or cleaned up if any keys change or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to

  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun UserProfile(userRepository: UserRepository, userRequest: UserDataRequest) {
    var userDataState by remember { mutableStateOf<UserDataState>(UserDataState.Loading) }

    // If either the repository or request change, we must cancel our old data fetch
    // and begin a new data fetch. We will cancel the current data fetch if UserProfile
    // leaves the composition.
    DisposableEffect(userRepository, userRequest) {
        val requestDisposable = userRepository.fetchUserData(
            userRequest,
            onSuccess = { response ->
                userDataState = UserDataState.UserData(response)
            },
            onError = { throwable ->
                userDataState = UserDataState.Error(throwable.message)
            }
        )

        onDispose {
            requestDisposable.dispose()
        }
    }

    // ...
}

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

DisposableEffect

@Composable
@NonRestartableComposable
fun DisposableEffect(key1: Any?, key2: Any?, effect: DisposableEffectScope.() -> DisposableEffectResult): Unit

A side effect of composition that must run for any new unique value of key1 or key2 and must be reversed or cleaned up if key1 or key2 changes, or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to

  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun UserProfile(userRepository: UserRepository, userRequest: UserDataRequest) {
    var userDataState by remember { mutableStateOf<UserDataState>(UserDataState.Loading) }

    // If either the repository or request change, we must cancel our old data fetch
    // and begin a new data fetch. We will cancel the current data fetch if UserProfile
    // leaves the composition.
    DisposableEffect(userRepository, userRequest) {
        val requestDisposable = userRepository.fetchUserData(
            userRequest,
            onSuccess = { response ->
                userDataState = UserDataState.UserData(response)
            },
            onError = { throwable ->
                userDataState = UserDataState.Error(throwable.message)
            }
        )

        onDispose {
            requestDisposable.dispose()
        }
    }

    // ...
}

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

DisposableEffect

@Composable
@NonRestartableComposable
fun DisposableEffect(
    key1: Any?,
    key2: Any?,
    key3: Any?,
    effect: DisposableEffectScope.() -> DisposableEffectResult
): Unit

A side effect of composition that must run for any new unique value of key1, key2 or key3 and must be reversed or cleaned up if key1, key2 or key3 changes, or if the DisposableEffect leaves the composition.

A DisposableEffect's key is a value that defines the identity of the DisposableEffect. If a key changes, the DisposableEffect must dispose its current effect and reset by calling effect again. Examples of keys include:

  • Observable objects that the effect subscribes to

  • Unique request parameters to an operation that must cancel and retry if those parameters change

DisposableEffect may be used to initialize or subscribe to a key and reinitialize when a different key is provided, performing cleanup for the old operation before initializing the new. For example:

import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun UserProfile(userRepository: UserRepository, userRequest: UserDataRequest) {
    var userDataState by remember { mutableStateOf<UserDataState>(UserDataState.Loading) }

    // If either the repository or request change, we must cancel our old data fetch
    // and begin a new data fetch. We will cancel the current data fetch if UserProfile
    // leaves the composition.
    DisposableEffect(userRepository, userRequest) {
        val requestDisposable = userRepository.fetchUserData(
            userRequest,
            onSuccess = { response ->
                userDataState = UserDataState.UserData(response)
            },
            onError = { throwable ->
                userDataState = UserDataState.Error(throwable.message)
            }
        )

        onDispose {
            requestDisposable.dispose()
        }
    }

    // ...
}

A DisposableEffect must include an onDispose clause as the final statement in its effect block. If your operation does not require disposal it might be a SideEffect instead, or a LaunchedEffect if it launches a coroutine that should be managed by the composition.

There is guaranteed to be one call to dispose for every call to effect. Both effect and dispose will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks.

LaunchedEffect

@Composable
fun LaunchedEffect(block: suspend CoroutineScope.() -> Unit): Unit

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext. The coroutine will be cancelled when the LaunchedEffect leaves the composition.

It is an error to call LaunchedEffect without at least one key parameter.

LaunchedEffect

@Composable
@NonRestartableComposable
fun LaunchedEffect(key1: Any?, block: suspend CoroutineScope.() -> Unit): Unit

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext. The coroutine will be cancelled and re-launched when LaunchedEffect is recomposed with a different key1. The coroutine will be cancelled when the LaunchedEffect leaves the composition.

This function should not be used to (re-)launch ongoing tasks in response to callback events by way of storing callback data in MutableState passed to key1. Instead, see rememberCoroutineScope to obtain a CoroutineScope that may be used to launch ongoing jobs scoped to the composition in response to event callbacks.

LaunchedEffect

@Composable
@NonRestartableComposable
fun LaunchedEffect(vararg keys: Any?, block: suspend CoroutineScope.() -> Unit): Unit

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext. The coroutine will be cancelled and re-launched when LaunchedEffect is recomposed with any different keys. The coroutine will be cancelled when the LaunchedEffect leaves the composition.

This function should not be used to (re-)launch ongoing tasks in response to callback events by way of storing callback data in MutableState passed to key. Instead, see rememberCoroutineScope to obtain a CoroutineScope that may be used to launch ongoing jobs scoped to the composition in response to event callbacks.

LaunchedEffect

@Composable
@NonRestartableComposable
fun LaunchedEffect(key1: Any?, key2: Any?, block: suspend CoroutineScope.() -> Unit): Unit

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext. The coroutine will be cancelled and re-launched when LaunchedEffect is recomposed with a different key1 or key2. The coroutine will be cancelled when the LaunchedEffect leaves the composition.

This function should not be used to (re-)launch ongoing tasks in response to callback events by way of storing callback data in MutableState passed to key. Instead, see rememberCoroutineScope to obtain a CoroutineScope that may be used to launch ongoing jobs scoped to the composition in response to event callbacks.

LaunchedEffect

@Composable
@NonRestartableComposable
fun LaunchedEffect(key1: Any?, key2: Any?, key3: Any?, block: suspend CoroutineScope.() -> Unit): Unit

When LaunchedEffect enters the composition it will launch block into the composition's CoroutineContext. The coroutine will be cancelled and re-launched when LaunchedEffect is recomposed with a different key1, key2 or key3. The coroutine will be cancelled when the LaunchedEffect leaves the composition.

This function should not be used to (re-)launch ongoing tasks in response to callback events by way of storing callback data in MutableState passed to key. Instead, see rememberCoroutineScope to obtain a CoroutineScope that may be used to launch ongoing jobs scoped to the composition in response to event callbacks.

ReusableComposeNode

@Composable
inline fun <T : Any, E : Applier<*>> ReusableComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit
): Unit

Emits a recyclable node into the composition of type T.

This function will throw a runtime exception if E is not a subtype of the applier of the currentComposer.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
noinline factory: () -> T

A function which will create a new instance of T. This function is NOT guaranteed to be called in place.

update: @DisallowComposableCalls Updater<T>.() -> Unit

A function to perform updates on the node. This will run every time emit is executed. This function is called in place and will be inlined.

ReusableComposeNode

@Composable
inline fun <T : Any?, E : Applier<*>> ReusableComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    content: @Composable () -> Unit
): Unit

Emits a recyclable node into the composition of type T. Nodes emitted inside of content will become children of the emitted node.

This function will throw a runtime exception if E is not a subtype of the applier of the currentComposer.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
noinline factory: () -> T

A function which will create a new instance of T. This function is NOT guaranteed to be called in place.

update: @DisallowComposableCalls Updater<T>.() -> Unit

A function to perform updates on the node. This will run every time emit is executed. This function is called in place and will be inlined.

content: @Composable () -> Unit

the composable content that will emit the "children" of this node.

ReusableComposeNode

@Composable
@ExplicitGroupsComposable
inline fun <T : Any?, E : Applier<*>> ReusableComposeNode(
    noinline factory: () -> T,
    update: @DisallowComposableCalls Updater<T>.() -> Unit,
    noinline skippableUpdate: @Composable SkippableUpdater<T>.() -> Unit,
    content: @Composable () -> Unit
): Unit

Emits a recyclable node into the composition of type T. Nodes emitted inside of content will become children of the emitted node.

This function will throw a runtime exception if E is not a subtype of the applier of the currentComposer.

import androidx.compose.runtime.ComposeNode
import androidx.compose.runtime.Composition
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

// Provided we have a tree with a node base type like the following
abstract class Node {
    val children = mutableListOf<Node>()
}

// We would implement an Applier class like the following, which would teach compose how to
// manage a tree of Nodes.
class NodeApplier(root: Node) : AbstractApplier<Node>(root) {
    override fun insertTopDown(index: Int, instance: Node) {
        current.children.add(index, instance)
    }

    override fun insertBottomUp(index: Int, instance: Node) {
        // Ignored as the tree is built top-down.
    }

    override fun remove(index: Int, count: Int) {
        current.children.remove(index, count)
    }

    override fun move(from: Int, to: Int, count: Int) {
        current.children.move(from, to, count)
    }

    override fun onClear() {
        root.children.clear()
    }
}

// A function like the following could be created to create a composition provided a root Node.
fun Node.setContent(
    parent: CompositionContext,
    content: @Composable () -> Unit
): Composition {
    return Composition(NodeApplier(this), parent).apply {
        setContent(content)
    }
}

// assuming we have Node sub-classes like "TextNode" and "GroupNode"
class TextNode : Node() {
    var text: String = ""
    var onClick: () -> Unit = {}
}
class GroupNode : Node()

// Composable equivalents could be created
@Composable fun Text(text: String, onClick: () -> Unit = {}) {
    ComposeNode<TextNode, NodeApplier>(::TextNode) {
        set(text) { this.text = it }
        set(onClick) { this.onClick = it }
    }
}

@Composable fun Group(content: @Composable () -> Unit) {
    ComposeNode<GroupNode, NodeApplier>(::GroupNode, {}, content)
}

// and then a sample tree could be composed:
fun runApp(root: GroupNode, parent: CompositionContext) {
    root.setContent(parent) {
        var count by remember { mutableStateOf(0) }
        Group {
            Text("Count: $count")
            Text("Increment") { count++ }
        }
    }
}
Parameters
noinline factory: () -> T

A function which will create a new instance of T. This function is NOT guaranteed to be called in place.

update: @DisallowComposableCalls Updater<T>.() -> Unit

A function to perform updates on the node. This will run every time emit is executed. This function is called in place and will be inlined.

noinline skippableUpdate: @Composable SkippableUpdater<T>.() -> Unit

A function to perform updates on the node. Unlike update, this function is Composable and will therefore be skipped unless it has been invalidated by some other mechanism. This can be useful to perform expensive calculations for updating the node where the calculations are likely to have the same inputs over time, so the function's execution can be skipped.

content: @Composable () -> Unit

the composable content that will emit the "children" of this node.

ReusableComposition

fun ReusableComposition(applier: Applier<*>, parent: CompositionContext): ReusableComposition

This method is the way to initiate a reusable composition. parent can be provided to make the composition behave as a sub-composition of the parent. If composition does not have a parent, Recomposer instance should be provided.

It is important to call Composition.dispose when composition is no longer needed in order to release resources.

Parameters
applier: Applier<*>

The Applier instance to be used in the composition.

parent: CompositionContext

The parent CompositionContext.

ReusableContent

@Composable
inline fun ReusableContent(key: Any?, content: @Composable () -> Unit): Unit

A utility function to mark a composition as supporting recycling. If the key changes the composition is replaced by a new composition (as would happen for key) but reusable nodes that are emitted by ReusableComposeNode are reused.

Parameters
key: Any?

the value that is used to trigger recycling. If recomposed with a different value the composer creates a new composition but tries to reuse reusable nodes.

content: @Composable () -> Unit

the composable children that are recyclable.

ReusableContentHost

@Composable
@ExplicitGroupsComposable
inline fun ReusableContentHost(
    active: Boolean,
    crossinline content: @Composable () -> Unit
): Unit

An optional utility function used when hosting ReusableContent. If active is false the content is treated as if it is deleted by removing all remembered objects from the composition but the node produced for the tree are not removed. When the composition later becomes active then the nodes are able to be reused inside ReusableContent content without requiring the remembered state of the composition's lifetime being arbitrarily extended.

Parameters
active: Boolean

when active is true content is composed normally. When active is false then the content is deactivated and all remembered state is treated as if the content was deleted but the nodes managed by the composition's Applier are unaffected. A active becomes true any reusable nodes from the previously active composition are candidates for reuse.

crossinline content: @Composable () -> Unit

the composable content that is managed by this composable.

SideEffect

@Composable
@NonRestartableComposable
@ExplicitGroupsComposable
fun SideEffect(effect: () -> Unit): Unit

Schedule effect to run when the current composition completes successfully and applies changes. SideEffect can be used to apply side effects to objects managed by the composition that are not backed by snapshots so as not to leave those objects in an inconsistent state if the current composition operation fails.

effect will always be run on the composition's apply dispatcher and appliers are never run concurrent with themselves, one another, applying changes to the composition tree, or running RememberObserver event callbacks. SideEffects are always run after RememberObserver event callbacks.

A SideEffect runs after every recomposition. To launch an ongoing task spanning potentially many recompositions, see LaunchedEffect. To manage an event subscription or other object lifecycle, see DisposableEffect.

compositionLocalOf

fun <T : Any?> compositionLocalOf(
    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy(),
    defaultFactory: () -> T
): ProvidableCompositionLocal<T>

Create a CompositionLocal key that can be provided using CompositionLocalProvider. Changing the value provided during recomposition will invalidate the content of CompositionLocalProvider that read the value using CompositionLocal.current.

compositionLocalOf creates a ProvidableCompositionLocal which can be used in a a call to CompositionLocalProvider. Similar to MutableList vs. List, if the key is made public as CompositionLocal instead of ProvidableCompositionLocal, it can be read using CompositionLocal.current but not re-provided.

Parameters
policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()

a policy to determine when a CompositionLocal is considered changed. See SnapshotMutationPolicy for details.

defaultFactory: () -> T

a value factory to supply a value when a value is not provided. This factory is called when no value is provided through a CompositionLocalProvider of the caller of the component using CompositionLocal.current. If no reasonable default can be provided then consider throwing an exception.

derivedStateOf

@StateFactoryMarker
fun <T : Any?> derivedStateOf(calculation: () -> T): State<T>

Creates a State object whose State.value is the result of calculation. The result of calculation will be cached in such a way that calling State.value repeatedly will not cause calculation to be executed multiple times, but reading State.value will cause all State objects that got read during the calculation to be read in the current Snapshot, meaning that this will correctly subscribe to the derived state objects if the value is being read in an observed context such as a Composable function. Derived states without mutation policy trigger updates on each dependency change. To avoid invalidation on update, provide suitable SnapshotMutationPolicy through derivedStateOf overload.

import androidx.compose.material.Text
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable fun CountDisplay(count: State<Int>) {
    Text("Count: ${count.value}")
}

@Composable fun Example() {
    var a by remember { mutableStateOf(0) }
    var b by remember { mutableStateOf(0) }
    val sum = remember { derivedStateOf { a + b } }
    // Changing either a or b will cause CountDisplay to recompose but not trigger Example
    // to recompose.
    CountDisplay(sum)
}
Parameters
calculation: () -> T

the calculation to create the value this state object represents.

derivedStateOf

@StateFactoryMarker
fun <T : Any?> derivedStateOf(
    policy: SnapshotMutationPolicy<T>,
    calculation: () -> T
): State<T>

Creates a State object whose State.value is the result of calculation. The result of calculation will be cached in such a way that calling State.value repeatedly will not cause calculation to be executed multiple times, but reading State.value will cause all State objects that got read during the calculation to be read in the current Snapshot, meaning that this will correctly subscribe to the derived state objects if the value is being read in an observed context such as a Composable function.

import androidx.compose.material.Text
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable fun CountDisplay(count: State<Int>) {
    Text("Count: ${count.value}")
}

@Composable fun Example() {
    var a by remember { mutableStateOf(0) }
    var b by remember { mutableStateOf(0) }
    val sum = remember { derivedStateOf { a + b } }
    // Changing either a or b will cause CountDisplay to recompose but not trigger Example
    // to recompose.
    CountDisplay(sum)
}
Parameters
policy: SnapshotMutationPolicy<T>

mutation policy to control when changes to the calculation result trigger update.

calculation: () -> T

the calculation to create the value this state object represents.

isTraceInProgress

@ComposeCompilerApi
fun isTraceInProgress(): Boolean

Internal tracing API.

Should be called without thread synchronization with occasional information loss.

@Composable
inline fun <T : Any?> key(vararg keys: Any?, block: @Composable () -> T): T

key is a utility composable that is used to "group" or "key" a block of execution inside of a composition. This is sometimes needed for correctness inside of control-flow that may cause a given composable invocation to execute more than once during composition.

The value for a key does not need to be globally unique, and needs only be unique amongst the invocations of key at that point in composition.

For instance, consider the following example:

import androidx.compose.runtime.key

for (user in users) {
    key(user.id) { UserPreview(user = user) }
}

for (user in users.filter { isAdmin }) {
    key(user.id) { Friend(friend = user) }
}

Even though there are users with the same id composed in both the top and the bottom loop, because they are different calls to key, there is no need to create compound keys.

The key must be unique for each element in the collection, however, or children and local state might be reused in unintended ways.

For instance, consider the following example:

import androidx.compose.runtime.key

for ((child, parent) in relationships) {
    key(parent.id) {
        User(user = child)
        User(user = parent)
    }
}

This example assumes that parent.id is a unique key for each item in the collection, but this is only true if it is fair to assume that a parent will only ever have a single child, which may not be the case. Instead, it may be more correct to do the following:

import androidx.compose.runtime.key

for ((child, parent) in relationships) {
    key(parent.id to child.id) {
        User(user = child)
        User(user = parent)
    }
}

A compound key can be created by passing in multiple arguments:

import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

for (element in elements) {
    val selected by key(element.id, parentId) { remember { mutableStateOf(false) } }
    ListItem(item = element, selected = selected)
}
Parameters
vararg keys: Any?

The set of values to be used to create a compound key. These will be compared to their previous values using equals and hashCode

block: @Composable () -> T

The composable children for this group.

movableContentOf

fun movableContentOf(content: @Composable () -> Unit): @Composable () -> Unit

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable () -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable () -> Unit

A tracking composable lambda

movableContentOf

fun <P : Any?> movableContentOf(content: @Composable (P) -> Unit): @Composable (P) -> Unit

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable (P) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable (P) -> Unit

A tracking composable lambda

movableContentOf

fun <P1 : Any?, P2 : Any?> movableContentOf(content: @Composable (P1, P2) -> Unit): @Composable (P1, P2) -> Unit

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable (P1, P2) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable (P1, P2) -> Unit

A tracking composable lambda

movableContentOf

fun <P1 : Any?, P2 : Any?, P3 : Any?> movableContentOf(
    content: @Composable (P1, P2, P3) -> Unit
): @Composable (P1, P2, P3) -> Unit

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable (P1, P2, P3) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable (P1, P2, P3) -> Unit

A tracking composable lambda

movableContentOf

fun <P1 : Any?, P2 : Any?, P3 : Any?, P4 : Any?> movableContentOf(
    content: @Composable (P1, P2, P3, P4) -> Unit
): @Composable (P1, P2, P3, P4) -> Unit

Convert a lambda into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable (P1, P2, P3, P4) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable (P1, P2, P3, P4) -> Unit

A tracking composable lambda

movableContentWithReceiverOf

fun <R : Any?> movableContentWithReceiverOf(content: @Composable R.() -> Unit): @Composable R.() -> Unit

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable R.() -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable R.() -> Unit

A tracking composable lambda

movableContentWithReceiverOf

fun <R : Any?, P : Any?> movableContentWithReceiverOf(content: @Composable R.(P) -> Unit): @Composable R.(P) -> Unit

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable R.(P) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable R.(P) -> Unit

A tracking composable lambda

movableContentWithReceiverOf

fun <R : Any?, P1 : Any?, P2 : Any?> movableContentWithReceiverOf(
    content: @Composable R.(P1, P2) -> Unit
): @Composable R.(P1, P2) -> Unit

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable R.(P1, P2) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable R.(P1, P2) -> Unit

A tracking composable lambda

movableContentWithReceiverOf

fun <R : Any?, P1 : Any?, P2 : Any?, P3 : Any?> movableContentWithReceiverOf(
    content: @Composable R.(P1, P2, P3) -> Unit
): @Composable R.(P1, P2, P3) -> Unit

Convert a lambda with a receiver into one that moves the remembered state and nodes created in a previous call to the new location it is called.

Tracking compositions can be used to produce a composable that moves its content between a row and a column based on a parameter, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val movableContent = remember(content) { movableContentOf(content) }

if (vertical) {
    Column {
        movableContent()
    }
} else {
    Row {
        movableContent()
    }
}

Or they can be used to ensure the composition state tracks with a model as moves in the layout, such as,

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.runtime.movableContentOf
import androidx.compose.runtime.remember

val itemMap = remember {
    mutableMapOf<Item, @Composable () -> Unit>()
}
val movableItems =
    items.map { item -> itemMap.getOrPut(item) { movableContentOf { ItemView(item) } } }

val itemsPerColumn = 10
val columns = items.size / itemsPerColumn + (if (items.size % itemsPerColumn == 0) 0 else 1)
Row {
    repeat(columns) { column ->
        Column {
            val base = column * itemsPerColumn
            val end = minOf(base + itemsPerColumn, items.size)
            for (index in base until end) {
                movableItems[index]()
            }
        }
    }
}
Parameters
content: @Composable R.(P1, P2, P3) -> Unit

The composable lambda to convert into a state tracking lambda.

Returns
@Composable R.(P1, P2, P3) -> Unit

A tracking composable lambda

mutableDoubleStateOf

@StateFactoryMarker
fun mutableDoubleStateOf(value: Double): MutableDoubleState

Return a new MutableDoubleState initialized with the passed in value

The MutableDoubleState class is a single value holder whose reads and writes are observed by Compose. Additionally, writes to it are transacted as part of the Snapshot system. On the JVM, values are stored in memory as the primitive double type, avoiding the autoboxing that occurs when using MutableState<Double>.

Parameters
value: Double

the initial value for the MutableDoubleState

mutableFloatStateOf

@StateFactoryMarker
fun mutableFloatStateOf(value: Float): MutableFloatState

Return a new MutableFloatState initialized with the passed in value

The MutableFloatState class is a single value holder whose reads and writes are observed by Compose. Additionally, writes to it are transacted as part of the Snapshot system. On the JVM, values are stored in memory as the primitive float type, avoiding the autoboxing that occurs when using MutableState<Float>.

Parameters
value: Float

the initial value for the MutableFloatState

mutableIntStateOf

@StateFactoryMarker
fun mutableIntStateOf(value: Int): MutableIntState

Return a new MutableIntState initialized with the passed in value

The MutableIntState class is a single value holder whose reads and writes are observed by Compose. Additionally, writes to it are transacted as part of the Snapshot system. On the JVM, values are stored in memory as the primitive int type, avoiding the autoboxing that occurs when using MutableState<Int>.

Parameters
value: Int

the initial value for the MutableIntState

mutableLongStateOf

@StateFactoryMarker
fun mutableLongStateOf(value: Long): MutableLongState

Return a new MutableLongState initialized with the passed in value

The MutableLongState class is a single value holder whose reads and writes are observed by Compose. Additionally, writes to it are transacted as part of the Snapshot system. On the JVM, values are stored in memory as the primitive long type, avoiding the autoboxing that occurs when using MutableState<Long>.

Parameters
value: Long

the initial value for the MutableLongState

mutableStateListOf

@StateFactoryMarker
fun <T : Any?> mutableStateListOf(): SnapshotStateList<T>

Create a instance of MutableList that is observable and can be snapshot.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateListOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun Names() {
    var name by remember { mutableStateOf("user") }
    val names = remember { mutableStateListOf<String>() }

    Column {
        Row {
            BasicTextField(
                value = name,
                onValueChange = { name = it }
            )
            Button(onClick = { names.add(name) }) {
                Text("Add")
            }
        }
        Text("Added names:")
        Column {
            for (addedName in names) {
                Text(addedName)
            }
        }
    }
}

mutableStateListOf

@StateFactoryMarker
fun <T : Any?> mutableStateListOf(vararg elements: T): SnapshotStateList<T>

Create an instance of MutableList that is observable and can be snapshot.

mutableStateMapOf

@StateFactoryMarker
fun <K : Any?, V : Any?> mutableStateMapOf(): SnapshotStateMap<K, V>

Create a instance of MutableMap that is observable and can be snapshot.

import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateMapOf
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun NamesAndAges() {
    var name by remember { mutableStateOf("name") }
    var saying by remember { mutableStateOf("saying") }
    val sayings = remember {
        mutableStateMapOf(
            "Caesar" to "Et tu, Brute?",
            "Hamlet" to "To be or not to be",
            "Richard III" to "My kingdom for a horse"
        )
    }

    Column {
        Row {
            BasicTextField(
                value = name,
                onValueChange = { name = it }
            )
            BasicTextField(
                value = saying,
                onValueChange = { saying = it }
            )
            Button(onClick = { sayings[name] = saying }) {
                Text("Add")
            }
            Button(onClick = { sayings.remove(name) }) {
                Text("Remove")
            }
        }
        Text("Sayings:")
        Column {
            for (entry in sayings) {
                Text("${entry.key} says '${entry.value}'")
            }
        }
    }
}

mutableStateMapOf

@StateFactoryMarker
fun <K : Any?, V : Any?> mutableStateMapOf(vararg pairs: Pair<K, V>): SnapshotStateMap<K, V>

Create a instance of MutableMap that is observable and can be snapshot.

mutableStateOf

@StateFactoryMarker
fun <T : Any?> mutableStateOf(
    value: T,
    policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()
): MutableState<T>

Return a new MutableState initialized with the passed in value

The MutableState class is a single value holder whose reads and writes are observed by Compose. Additionally, writes to it are transacted as part of the Snapshot system.

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val count = remember { mutableStateOf(0) }

Text(text = "You clicked ${count.value} times")
Button(onClick = { count.value++ }) {
    Text("Click me")
}
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

val (count, setCount) = remember { mutableStateOf(0) }

Text(text = "You clicked $count times")
Button(onClick = { setCount(count + 1) }) {
    Text("Click me")
}
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun observeUser(userId: Int): User? {
    val user = remember(userId) { mutableStateOf<User?>(null) }
    DisposableEffect(userId) {
        val subscription = UserAPI.subscribeToUser(userId) {
            user.value = it
        }
        onDispose {
            subscription.unsubscribe()
        }
    }
    return user.value
}
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

@Composable
fun LoginScreen() {
    var username by remember { mutableStateOf("user") }
    var password by remember { mutableStateOf("pass") }

    fun login() = Api.login(username, password)

    BasicTextField(
        value = username,
        onValueChange = { username = it }
    )
    BasicTextField(
        value = password,
        onValueChange = { password = it }
    )
    Button(onClick = { login() }) {
        Text("Login")
    }
}
Parameters
value: T

the initial value for the MutableState

policy: SnapshotMutationPolicy<T> = structuralEqualityPolicy()

a policy to controls how changes are handled in mutable snapshots.

neverEqualPolicy

fun <T : Any?> neverEqualPolicy(): SnapshotMutationPolicy<T>

A policy never treat values of a MutableState as equivalent.

Setting MutableState.value will always be considered a change. When applying a MutableSnapshot that changes the state will always conflict with other snapshots that change the same state.

produceState

@Composable
fun <T : Any?> produceState(initialValue: T, producer: suspend ProduceStateScope<T>.() -> Unit): State<T>

Return an observable snapshot State that produces values over time without a defined data source.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
fun <T : Any?> produceState(initialValue: T, key1: Any?, producer: suspend ProduceStateScope<T>.() -> Unit): State<T>

Return an observable snapshot State that produces values over time from key1.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If key1 changes, a running producer will be cancelled and re-launched for the new source. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
fun <T : Any?> produceState(
    initialValue: T,
    vararg keys: Any?,
    producer: suspend ProduceStateScope<T>.() -> Unit
): State<T>

Return an observable snapshot State that produces values over time from keys.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If keys change, a running producer will be cancelled and re-launched for the new source. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
fun <T : Any?> produceState(
    initialValue: T,
    key1: Any?,
    key2: Any?,
    producer: suspend ProduceStateScope<T>.() -> Unit
): State<T>

Return an observable snapshot State that produces values over time from key1 and key2.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If key1 or key2 change, a running producer will be cancelled and re-launched for the new source. producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

produceState

@Composable
fun <T : Any?> produceState(
    initialValue: T,
    key1: Any?,
    key2: Any?,
    key3: Any?,
    producer: suspend ProduceStateScope<T>.() -> Unit
): State<T>

Return an observable snapshot State that produces values over time from key1, key2 and key3.

producer is launched when produceState enters the composition and is cancelled when produceState leaves the composition. If key1, key2 or key3 change, a running producer will be cancelled and re-launched for the new source. [producer should use ProduceStateScope.value to set new values on the returned State.

The returned State conflates values; no change will be observable if ProduceStateScope.value is used to set a value that is equal to its old value, and observers may only see the latest value if several values are set in rapid succession.

produceState may be used to observe either suspending or non-suspending sources of external data, for example:

import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.produceState

val uiState by produceState<UiState<List<Person>>>(UiState.Loading, viewModel) {
    viewModel.people
        .map { UiState.Data(it) }
        .collect { value = it }
}

when (val state = uiState) {
    is UiState.Loading -> Text("Loading...")
    is UiState.Data -> Column {
        for (person in state.data) {
            Text("Hello, ${person.name}")
        }
    }
}
import androidx.compose.runtime.produceState

val currentPerson by produceState<Person?>(null, viewModel) {
    val disposable = viewModel.registerPersonObserver { person ->
        value = person
    }

    awaitDispose {
        disposable.dispose()
    }
}

referentialEqualityPolicy

fun <T : Any?> referentialEqualityPolicy(): SnapshotMutationPolicy<T>

A policy to treat values of a MutableState as equivalent if they are referentially (===) equal.

Setting MutableState.value to its current referentially (===) equal value is not considered a change. When applying a MutableSnapshot, if the snapshot changes the value to the equivalent value the parent snapshot has is not considered a conflict.

remember

@Composable
inline fun <T : Any?> remember(crossinline calculation: @DisallowComposableCalls () -> T): T

Remember the value produced by calculation. calculation will only be evaluated during the composition. Recomposition will always return the value produced by composition.

remember

@Composable
inline fun <T : Any?> remember(
    key1: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
): T

Remember the value returned by calculation if key1 compares equal (==) to the value it had in the previous composition, otherwise produce and remember a new value by calling calculation.

@Composable
inline fun <T : Any?> remember(
    vararg keys: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
): T

Remember the value returned by calculation if all values of keys are equal (==) to the values they had in the previous composition, otherwise produce and remember a new value by calling calculation.

remember

@Composable
inline fun <T : Any?> remember(
    key1: Any?,
    key2: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
): T

Remember the value returned by calculation if key1 and key2 are equal (==) to the values they had in the previous composition, otherwise produce and remember a new value by calling calculation.

remember

@Composable
inline fun <T : Any?> remember(
    key1: Any?,
    key2: Any?,
    key3: Any?,
    crossinline calculation: @DisallowComposableCalls () -> T
): T

Remember the value returned by calculation if key1, key2 and key3 are equal (==) to values they had in the previous composition, otherwise produce and remember a new value by calling calculation.

rememberCompositionContext

@Composable
fun rememberCompositionContext(): CompositionContext

An Effect to construct a CompositionContext at the current point of composition. This can be used to run a separate composition in the context of the current one, preserving CompositionLocals and propagating invalidations. When this call leaves the composition, the context is invalidated.

rememberCoroutineScope

@Composable
inline fun rememberCoroutineScope(
    crossinline getContext: @DisallowComposableCalls () -> CoroutineContext = { EmptyCoroutineContext }
): CoroutineScope

Return a CoroutineScope bound to this point in the composition using the optional CoroutineContext provided by getContext. getContext will only be called once and the same CoroutineScope instance will be returned across recompositions.

This scope will be cancelled when this call leaves the composition. The CoroutineContext returned by getContext may not contain a Job as this scope is considered to be a child of the composition.

The default dispatcher of this scope if one is not provided by the context returned by getContext will be the applying dispatcher of the composition's Recomposer.

Use this scope to launch jobs in response to callback events such as clicks or other user interaction where the response to that event needs to unfold over time and be cancelled if the composable managing that process leaves the composition. Jobs should never be launched into any coroutine scope as a side effect of composition itself. For scoped ongoing jobs initiated by composition, see LaunchedEffect.

This function will not throw if preconditions are not met, as composable functions do not yet fully support exceptions. Instead the returned scope's CoroutineScope.coroutineContext will contain a failed Job with the associated exception and will not be capable of launching child jobs.

rememberUpdatedState

@Composable
fun <T : Any?> rememberUpdatedState(newValue: T): State<T>

remember a mutableStateOf and update its value to newValue on each recomposition of the rememberUpdatedState call.

rememberUpdatedState should be used when parameters or values computed during composition are referenced by a long-lived lambda or object expression. Recomposition will update the resulting State without recreating the long-lived lambda or object, allowing that object to persist without cancelling and resubscribing, or relaunching a long-lived operation that may be expensive or prohibitive to recreate and restart. This may be common when working with DisposableEffect or LaunchedEffect, for example:

import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.rememberUpdatedState

@Composable
fun EventHandler(dispatcher: Dispatcher, onEvent: () -> Unit) {
    val currentOnEvent by rememberUpdatedState(onEvent)

    // Event handlers are ordered and a new onEvent should not cause us to re-register,
    // losing our position in the dispatcher.
    DisposableEffect(dispatcher) {
        val disposable = dispatcher.addListener {
            // currentOnEvent will always refer to the latest onEvent function that
            // the EventHandler was recomposed with
            currentOnEvent()
        }
        onDispose {
            disposable.dispose()
        }
    }
}

LaunchedEffects often describe state machines that should not be reset and restarted if a parameter or event callback changes, but they should have the current value available when needed. For example:

import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberUpdatedState

@Composable
fun NotificationHost(state: NotificationState, onTimeout: (Notification) -> Unit) {
    val currentOnTimeout by rememberUpdatedState(onTimeout)

    state.currentNotification?.let { currentNotification ->
        LaunchedEffect(currentNotification) {
            // We should not restart this delay if onTimeout changes, but we want to call
            // the onTimeout we were last recomposed with when it completes.
            delay(NotificationTimeout)
            currentOnTimeout(currentNotification)
        }
    }

    // ...
}

By using rememberUpdatedState a composable function can update these operations in progress.

snapshotFlow

fun <T : Any?> snapshotFlow(block: () -> T): Flow<T>

Create a Flow from observable Snapshot state. (e.g. state holders returned by mutableStateOf.)

snapshotFlow creates a Flow that runs block when collected and emits the result, recording any snapshot state that was accessed. While collection continues, if a new Snapshot is applied that changes state accessed by block, the flow will run block again, re-recording the snapshot state that was accessed. If the result of block is not equal to the previous result, the flow will emit that new result. (This behavior is similar to that of Flow.distinctUntilChanged.) Collection will continue indefinitely unless it is explicitly cancelled or limited by the use of other Flow operators.

import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.snapshotFlow

// Define Snapshot state objects
var greeting by mutableStateOf("Hello")
var person by mutableStateOf("Adam")

// ...

// Create a flow that will emit whenever our person-specific greeting changes
val greetPersonFlow = snapshotFlow { "$greeting, $person" }

// ...

val collectionScope: CoroutineScope = TODO("Use your scope here")

// Collect the flow and offer greetings!
collectionScope.launch {
    greetPersonFlow.collect {
        println(greeting)
    }
}

// ...

// Change snapshot state; greetPersonFlow will emit a new greeting
Snapshot.withMutableSnapshot {
    greeting = "Ahoy"
    person = "Sean"
}

block is run in a read-only Snapshot and may not modify snapshot data. If block attempts to modify snapshot data, flow collection will fail with IllegalStateException.

block may run more than once for equal sets of inputs or only once after many rapid snapshot changes; it should be idempotent and free of side effects.

When working with Snapshot state it is useful to keep the distinction between events and state in mind. snapshotFlow models snapshot changes as events, but events cannot be effectively modeled as observable state. Observable state is a lossy compression of the events that produced that state.

An observable event happens at a point in time and is discarded. All registered observers at the time the event occurred are notified. All individual events in a stream are assumed to be relevant and may build on one another; repeated equal events have meaning and therefore a registered observer must observe all events without skipping.

Observable state raises change events when the state changes from one value to a new, unequal value. State change events are conflated; only the most recent state matters. Observers of state changes must therefore be idempotent; given the same state value the observer should produce the same result. It is valid for a state observer to both skip intermediate states as well as run multiple times for the same state and the result should be the same.

sourceInformation

@ComposeCompilerApi
fun sourceInformation(composer: Composer, sourceInformation: String): Unit

A Compose internal function. DO NOT call directly.

Records source information that can be used for tooling to determine the source location of the corresponding composable function. By default, this function is declared as having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove it.

sourceInformationMarkerEnd

@ComposeCompilerApi
fun sourceInformationMarkerEnd(composer: Composer): Unit

A Compose internal function. DO NOT call directly.

Records the end of a source information marker that can be used for tooling to determine the source location of the corresponding composable function that otherwise don't require tracking information such as ReadOnlyComposable functions. By default, this function is declared as having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove it.

Important that both sourceInformationMarkerStart and sourceInformationMarkerEnd are removed together or both kept. Removing only one will cause incorrect runtime behavior.

sourceInformationMarkerStart

@ComposeCompilerApi
fun sourceInformationMarkerStart(
    composer: Composer,
    key: Int,
    sourceInformation: String
): Unit

A Compose internal function. DO NOT call directly.

Records the start of a source information marker that can be used for tooling to determine the source location of the corresponding composable function that otherwise don't require tracking information such as ReadOnlyComposable functions. By default, this function is declared as having no side-effects. It is safe for code shrinking tools (such as R8 or ProGuard) to remove it.

Important that both sourceInformationMarkerStart and sourceInformationMarkerEnd are removed together or both kept. Removing only one will cause incorrect runtime behavior.

staticCompositionLocalOf

fun <T : Any?> staticCompositionLocalOf(defaultFactory: () -> T): ProvidableCompositionLocal<T>

Create a CompositionLocal key that can be provided using CompositionLocalProvider.

Unlike compositionLocalOf, reads of a staticCompositionLocalOf are not tracked by the composer and changing the value provided in the CompositionLocalProvider call will cause the entirety of the content to be recomposed instead of just the places where in the composition the local value is used. This lack of tracking, however, makes a staticCompositionLocalOf more efficient when the value provided is highly unlikely to or will never change. For example, the android context, font loaders, or similar shared values, are unlikely to change for the components in the content of a the CompositionLocalProvider and should consider using a staticCompositionLocalOf. A color, or other theme like value, might change or even be animated therefore a compositionLocalOf should be used.

staticCompositionLocalOf creates a ProvidableCompositionLocal which can be used in a a call to CompositionLocalProvider. Similar to MutableList vs. List, if the key is made public as CompositionLocal instead of ProvidableCompositionLocal, it can be read using CompositionLocal.current but not re-provided.

Parameters
defaultFactory: () -> T

a value factory to supply a value when a value is not provided. This factory is called when no value is provided through a CompositionLocalProvider of the caller of the component using CompositionLocal.current. If no reasonable default can be provided then consider throwing an exception.

structuralEqualityPolicy

fun <T : Any?> structuralEqualityPolicy(): SnapshotMutationPolicy<T>

A policy to treat values of a MutableState as equivalent if they are structurally (==) equal.

Setting MutableState.value to its current structurally (==) equal value is not considered a change. When applying a MutableSnapshot, if the snapshot changes the value to the equivalent value the parent snapshot has is not considered a conflict.

traceEventEnd

@ComposeCompilerApi
fun traceEventEnd(): Unit

Internal tracing API.

Should be called without thread synchronization with occasional information loss.

traceEventStart

@ComposeCompilerApi
fun traceEventStart(key: Int, dirty1: Int, dirty2: Int, info: String): Unit

Internal tracing API.

Should be called without thread synchronization with occasional information loss.

Parameters
dirty1: Int

$dirty metadata: forced-recomposition and function parameters 1..10 if present

dirty2: Int

$dirty2 metadata: forced-recomposition and function parameters 11..20 if present

withFrameMillis

suspend fun <R : Any?> withFrameMillis(onFrame: (frameTimeMillis: Long) -> R): R

Suspends until a new frame is requested, immediately invokes onFrame with the frame time in milliseconds in the calling context of frame dispatch, then resumes with the result from onFrame.

frameTimeMillis should be used when calculating animation time deltas from frame to frame as it may be normalized to the target time for the frame, not necessarily a direct, "now" value.

The time base of the value provided by MonotonicFrameClock.withFrameMillis is implementation defined. Time values provided are monotonically increasing; after a call to withFrameMillis completes it must not provide a smaller value for a subsequent call.

This function will invoke MonotonicFrameClock.withFrameNanos using the calling CoroutineContext's MonotonicFrameClock and will throw an IllegalStateException if one is not present in the CoroutineContext.

withFrameNanos

suspend fun <R : Any?> withFrameNanos(onFrame: (frameTimeNanos: Long) -> R): R

Suspends until a new frame is requested, immediately invokes onFrame with the frame time in nanoseconds in the calling context of frame dispatch, then resumes with the result from onFrame.

frameTimeNanos should be used when calculating animation time deltas from frame to frame as it may be normalized to the target time for the frame, not necessarily a direct, "now" value.

The time base of the value provided by withFrameNanos is implementation defined. Time values provided are strictly monotonically increasing; after a call to withFrameNanos completes it must not provide the same value again for a subsequent call.

This function will invoke MonotonicFrameClock.withFrameNanos using the calling CoroutineContext's MonotonicFrameClock and will throw an IllegalStateException if one is not present in the CoroutineContext.

withRunningRecomposer

suspend fun <R : Any?> withRunningRecomposer(block: suspend CoroutineScope.(recomposer: Recomposer) -> R): R

Runs block with a new, active Recomposer applying changes in the calling CoroutineContext. The Recomposer will be closed after block returns. withRunningRecomposer will return once the Recomposer is Recomposer.State.ShutDown and all child jobs launched by block have joined.

Extension functions

asDoubleState

fun State<Double>.asDoubleState(): DoubleState

Converts a State<Double> (as in, a State of boxed Doubles) into a primitive-backed Double. The state will be automatically unboxed to the required primitive type. The returned state is read-only. The returned state will mirror the values of the base state and apply updates in the same way as the receiver defines.

On the JVM, this conversion does not avoid the autoboxing that Double attempts to escape, but instead is intended to allow interoperability between components that use either representation of a state of type Double.

asFloatState

fun State<Float>.asFloatState(): FloatState

Converts a State<Float> (as in, a State of boxed Floats) into a primitive-backed Float. The state will be automatically unboxed to the required primitive type. The returned state is read-only. The returned state will mirror the values of the base state and apply updates in the same way as the receiver defines.

On the JVM, this conversion does not avoid the autoboxing that Float attempts to escape, but instead is intended to allow interoperability between components that use either representation of a state of type Float.

asIntState

fun State<Int>.asIntState(): IntState

Converts a State<Int> (as in, a State of boxed Ints) into a primitive-backed IntState. The state will be automatically unboxed to the required primitive type. The returned state is read-only. The returned state will mirror the values of the base state and apply updates in the same way as the receiver defines.

On the JVM, this conversion does not avoid the autoboxing that IntState attempts to escape, but instead is intended to allow interoperability between components that use either representation of a state of type Int.

asLongState

fun State<Long>.asLongState(): LongState

Converts a State<Long> (as in, a State of boxed Longs) into a primitive-backed LongState. The state will be automatically unboxed to the required primitive type. The returned state is read-only. The returned state will mirror the values of the base state and apply updates in the same way as the receiver defines.

On the JVM, this conversion does not avoid the autoboxing that LongState attempts to escape, but instead is intended to allow interoperability between components that use either representation of a state of type Long.

cache

@ComposeCompilerApi
inline fun <T : Any?> Composer.cache(
    invalid: Boolean,
    block: @DisallowComposableCalls () -> T
): T

A Compose compiler plugin API. DO NOT call directly.

Cache, that is remember, a value in the composition data of a composition. This is used to implement remember and used by the compiler plugin to generate more efficient calls to remember when it determines these optimizations are safe.

collectAsState

@Composable
fun <T : Any?> StateFlow<T>.collectAsState(
    context: CoroutineContext = EmptyCoroutineContext
): State<T>

Collects values from this StateFlow and represents its latest value via State. The StateFlow.value is used as an initial value. Every time there would be new value posted into the StateFlow the returned State will be updated causing recomposition of every State.value usage.

import androidx.compose.material.Text
import androidx.compose.runtime.collectAsState

val value: String by stateFlow.collectAsState()
Text("Value is $value")
Parameters
context: CoroutineContext = EmptyCoroutineContext

CoroutineContext to use for collecting.

collectAsState

@Composable
fun <T : R, R : Any?> Flow<T>.collectAsState(
    initial: R,
    context: CoroutineContext = EmptyCoroutineContext
): State<R>

Collects values from this Flow and represents its latest value via State. Every time there would be new value posted into the Flow the returned State will be updated causing recomposition of every State.value usage.

import androidx.compose.material.Text
import androidx.compose.runtime.collectAsState

val value: String by flow.collectAsState("initial")
Text("Value is $value")
Parameters
context: CoroutineContext = EmptyCoroutineContext

CoroutineContext to use for collecting.

getValue

inline operator fun DoubleState.getValue(thisObj: Any?, property: KProperty<*>): Double

Permits property delegation of vals using by for DoubleState.

inline operator fun FloatState.getValue(thisObj: Any?, property: KProperty<*>): Float

Permits property delegation of vals using by for FloatState.

getValue

inline operator fun IntState.getValue(thisObj: Any?, property: KProperty<*>): Int

Permits property delegation of vals using by for IntState.

getValue

inline operator fun LongState.getValue(thisObj: Any?, property: KProperty<*>): Long

Permits property delegation of vals using by for LongState.

inline operator fun <T : Any?> State<T>.getValue(thisObj: Any?, property: KProperty<*>): T

Permits property delegation of vals using by for State.

import androidx.compose.foundation.layout.Row
import androidx.compose.material.Text

// Composable function that manages a subscription to a data source, returning it as State
@Composable
fun observeSampleData(): State<String> = TODO()

// Subscription is managed here, but currentValue is not read yet
val currentValue by observeSampleData()

Row {
    // This scope will recompose when currentValue changes
    Text("Data: $currentValue")
}

setValue

inline operator fun MutableDoubleState.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: Double
): Unit

Permits property delegation of vars using by for MutableDoubleState.

inline operator fun MutableFloatState.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: Float
): Unit

Permits property delegation of vars using by for MutableFloatState.

setValue

inline operator fun MutableIntState.setValue(thisObj: Any?, property: KProperty<*>, value: Int): Unit

Permits property delegation of vars using by for MutableIntState.

setValue

inline operator fun MutableLongState.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: Long
): Unit

Permits property delegation of vars using by for MutableLongState.

setValue

inline operator fun <T : Any?> MutableState<T>.setValue(
    thisObj: Any?,
    property: KProperty<*>,
    value: T
): Unit

Permits property delegation of vars using by for MutableState.

import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember

var count by remember { mutableStateOf(0) }

Text(text = "You clicked $count times")
Button(onClick = { count = count + 1 }) {
    Text("Click me")
}

toMutableStateList

fun <T : Any?> Collection<T>.toMutableStateList(): SnapshotStateList<T>

Create an instance of MutableList from a collection that is observable and can be snapshot.

toMutableStateMap

fun <K : Any?, V : Any?> Iterable<Pair<K, V>>.toMutableStateMap(): SnapshotStateMap<K, V>

Create an instance of MutableMap from a collection of pairs that is observable and can be snapshot.

withFrameMillis

suspend inline fun <R : Any?> MonotonicFrameClock.withFrameMillis(
    crossinline onFrame: (frameTimeMillis: Long) -> R
): R

Suspends until a new frame is requested, immediately invokes onFrame with the frame time in milliseconds in the calling context of frame dispatch, then resumes with the result from onFrame.

frameTimeMillis should be used when calculating animation time deltas from frame to frame as it may be normalized to the target time for the frame, not necessarily a direct, "now" value.

The time base of the value provided by MonotonicFrameClock.withFrameMillis is implementation defined. Time values provided are monotonically increasing; after a call to withFrameMillis completes it must not provide a smaller value for a subsequent call.

Top-level properties

DefaultMonotonicFrameClock

val DefaultMonotonicFrameClockMonotonicFrameClock

The MonotonicFrameClock used by withFrameNanos and withFrameMillis if one is not present in the calling kotlin.coroutines.CoroutineContext.

This value is no longer used by compose runtime.

currentComposer

val currentComposerComposer

TODO(lmr): provide documentation

currentCompositeKeyHash

val currentCompositeKeyHashInt

This a hash value used to coordinate map externally stored state to the composition. For example, this is used by saved instance state to preserve state across activity lifetime boundaries.

This value is likely to be unique but is not guaranteed unique. There are known cases, such as for loops without a key, where the runtime does not have enough information to make the compound key hash unique.

currentCompositionLocalContext

val currentCompositionLocalContextCompositionLocalContext

Returns the current CompositionLocalContext which contains all CompositionLocal's in the current composition and their values provided by CompositionLocalProvider's. This context can be used to pass locals to another composition via CompositionLocalProvider. That is usually needed if another composition is not a subcomposition of the current one.

currentRecomposeScope

val currentRecomposeScopeRecomposeScope

Returns an object which can be used to invalidate the current scope at this point in composition. This object can be used to manually cause recompositions.

Extension properties

recomposeCoroutineContext

@ExperimentalComposeApi
val ControlledComposition.recomposeCoroutineContextCoroutineContext

The CoroutineContext that should be used to perform concurrent recompositions of this ControlledComposition when used in an environment supporting concurrent composition.

See Recomposer.runRecomposeConcurrentlyAndApplyChanges as an example of configuring such an environment.