CompositionLocalConsumerModifierNode


Implementing this interface allows your Modifier.Node subclass to read CompositionLocals via the currentValueOf function. The values of each CompositionLocal will be resolved based on the context of the layout node that the modifier is attached to, meaning that the modifier will see the same values of each CompositionLocal as its corresponding layout node.

import androidx.compose.foundation.layout.Box
import androidx.compose.material.Text
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.ContentDrawScope
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.DrawModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.platform.InspectorInfo

val localBackgroundColor = compositionLocalOf { Color.White }
class BackgroundColor :
    Modifier.Node(), DrawModifierNode, CompositionLocalConsumerModifierNode {
    override fun ContentDrawScope.draw() {
        val backgroundColor = currentValueOf(localBackgroundColor)
        drawRect(backgroundColor)
        drawContent()
    }
}
val backgroundColorElement =
    object : ModifierNodeElement<BackgroundColor>() {
        override fun create() = BackgroundColor()

        override fun update(node: BackgroundColor) {}

        override fun hashCode() = System.identityHashCode(this)

        override fun equals(other: Any?) = (other === this)

        override fun InspectorInfo.inspectableProperties() {
            name = "backgroundColor"
        }
    }
fun Modifier.backgroundColor() = this then backgroundColorElement
Box(Modifier.backgroundColor()) { Text("Hello, world!") }

Summary

Extension functions

T

Returns the current value of local at the position in the composition hierarchy of this modifier's attached layout node.

Cmn

Inherited functions

From androidx.compose.ui.node.DelegatableNode
open Unit

Invoked when the density changes for this node.

Cmn
open Unit

Invoked when the layout direction changes for this node.

Cmn

Inherited properties

From androidx.compose.ui.node.DelegatableNode
Modifier.Node

A reference of the Modifier.Node that holds this node's position in the node hierarchy.

Cmn

Extension functions

currentValueOf

fun <T : Any?> CompositionLocalConsumerModifierNode.currentValueOf(
    local: CompositionLocal<T>
): T

Returns the current value of local at the position in the composition hierarchy of this modifier's attached layout node.

Unlike CompositionLocal.current, reads via this function are not automatically tracked by Compose. Modifiers are not able to recompose in the same way that a Composable can, and therefore can't receive updates arbitrarily for a CompositionLocal.

Because CompositionLocals may change arbitrarily, it is strongly recommended to ensure that the composition local is observed instead of being read once. If you call currentValueOf inside of a modifier callback like LayoutModifierNode.measure or DrawModifierNode.draw, then Compose will track the CompositionLocal read. This happens automatically, because these Compose UI phases take place in a snapshot observer that tracks which states are read. If the value of the CompositionLocal changes, and it was read inside of the measure or draw phase, then that phase will automatically be invalidated.

For all other reads of a CompositionLocal, this function will not notify you when the value of the local changes. Modifier.Node classes that also implement ObserverModifierNode may observe CompositionLocals arbitrarily by performing the lookup in an observeReads block. To continue observing values of the CompositionLocal, it must be read again in an observeReads block during or after the ObserverModifierNode.onObservedReadsChanged callback is invoked. See below for an example of how to implement this observation pattern.

import androidx.compose.runtime.compositionLocalOf
import androidx.compose.ui.Modifier
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.ObserverModifierNode
import androidx.compose.ui.node.currentValueOf
import androidx.compose.ui.node.observeReads

val LocalValue = compositionLocalOf { "abc123" }
class ValueObserverModifierNode :
    Modifier.Node(), CompositionLocalConsumerModifierNode, ObserverModifierNode {
    private var observedValue: String? = null

    override fun onAttach() {
        onObservedReadsChanged()
    }

    override fun onDetach() {
        observedValue = null
    }

    override fun onObservedReadsChanged() {
        observeReads {
            observedValue = currentValueOf(LocalValue)
            // Do something with the new value
        }
    }
}

This function will fail with an IllegalStateException if you attempt to read a CompositionLocal before the node is attached or after the node is detached.

Parameters
local: CompositionLocal<T>

The CompositionLocal to get the current value of

Returns
T

The value provided by the nearest CompositionLocalProvider component that invokes, directly or indirectly, the composable function that this modifier is attached to. If local was never provided, its default value will be returned instead.