androidx.compose.ui

Interfaces

Alignment

An interface to calculate the position of a sized box inside an available space.

Cmn
Alignment.Horizontal

An interface to calculate the position of box of a certain width inside an available width.

Cmn
Alignment.Vertical

An interface to calculate the position of a box of a certain height inside an available height.

Cmn
Modifier

An ordered, immutable collection of modifier elements that decorate or add behavior to Compose UI elements.

Cmn
Modifier.Element

A single element contained within a Modifier chain.

Cmn
MotionDurationScale

Provides a duration scale for motion such as animations.

Cmn
UiMediaScope

A receiver scope that provides access to the properties of the current media environment.

Cmn

Classes

BiasAbsoluteAlignment

An Alignment specified by bias: for example, a bias of -1 represents alignment to the left/top, a bias of 0 will represent centering, and a bias of 1 will represent right/bottom.

Cmn
BiasAbsoluteAlignment.Horizontal

An Alignment.Horizontal specified by bias: for example, a bias of -1 represents alignment to the left, a bias of 0 will represent centering, and a bias of 1 will represent right.

Cmn
BiasAlignment

An Alignment specified by bias: for example, a bias of -1 represents alignment to the start/top, a bias of 0 will represent centering, and a bias of 1 will represent end/bottom.

Cmn
BiasAlignment.Horizontal

An Alignment.Horizontal specified by bias: for example, a bias of -1 represents alignment to the start, a bias of 0 will represent centering, and a bias of 1 will represent end.

Cmn
BiasAlignment.Vertical

An Alignment.Vertical specified by bias: for example, a bias of -1 represents alignment to the top, a bias of 0 will represent centering, and a bias of 1 will represent bottom.

Cmn
CombinedModifier

A node in a Modifier chain.

Cmn
FrameRateCategory

A type-safe representation of a frame rate category for a display or application.

Cmn
Modifier.Node

The longer-lived object that is created for each Modifier.Element applied to a androidx.compose.ui.layout.Layout.

Cmn
UiMediaScope.KeyboardKind

Describes the kind of keyboard available.

Cmn
UiMediaScope.PointerPrecision

Describes the precision of the available pointing devices.

Cmn
UiMediaScope.Posture

Describes the posture of the window, typically on a foldable device.

Cmn
UiMediaScope.ViewingDistance

Describes the typical distance between the user and the screen.

Cmn

Objects

AbsoluteAlignment

A collection of common Alignments unaware of the layout direction.

Cmn
AndroidComposeUiFlags

This is a collection of flags which are used to guard against regressions in some of the "riskier" refactors or new feature support that is added to this module.

android
ComposeUiFlags

This is a collection of flags which are used to guard against regressions in some of the "riskier" refactors or new feature support that is added to this module.

Cmn
Modifier.Companion

The companion object Modifier is the empty, default, or starter Modifier that contains no elements.

Cmn
MotionDurationScale.Key
Cmn

Annotations

ExperimentalComposeUiApi
Cmn
ExperimentalIndirectPointerApi
Cmn
ExperimentalMediaQueryApi
Cmn
InternalComposeUiApi

Unstable API for use only between compose-ui modules sharing the same exact version, subject to change without notice in major, minor, or patch releases.

Cmn
UiComposable

An annotation that can be used to mark a composable function as being expected to be use in a composable function that is also marked or inferred to be marked as a UiComposable.

Cmn

Top-level functions summary

State<Boolean>

Evaluates a boolean query against the current UiMediaScope, wrapped in a derivedStateOf.

Cmn
Boolean

Evaluates a boolean query against the current UiMediaScope.

Cmn

Extension functions summary

Modifier
Modifier.composed(
    inspectorInfo: InspectorInfo.() -> Unit,
    factory: @Composable Modifier.() -> Modifier
)

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies.

Cmn
Modifier
Modifier.composed(
    fullyQualifiedName: String,
    key1: Any?,
    inspectorInfo: InspectorInfo.() -> Unit,
    factory: @Composable Modifier.() -> Modifier
)

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies.

Cmn
Modifier
Modifier.composed(
    fullyQualifiedName: String,
    vararg keys: Any?,
    inspectorInfo: InspectorInfo.() -> Unit,
    factory: @Composable Modifier.() -> Modifier
)

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies.

Cmn
Modifier
Modifier.composed(
    fullyQualifiedName: String,
    key1: Any?,
    key2: Any?,
    inspectorInfo: InspectorInfo.() -> Unit,
    factory: @Composable Modifier.() -> Modifier
)

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies.

Cmn
Modifier
Modifier.composed(
    fullyQualifiedName: String,
    key1: Any?,
    key2: Any?,
    key3: Any?,
    inspectorInfo: InspectorInfo.() -> Unit,
    factory: @Composable Modifier.() -> Modifier
)

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies.

Cmn
Modifier

A modifier that keeps the device screen on as long as it is part of the composition on supported platforms.

Cmn
Modifier

Materialize any instance-specific composed modifiers for applying to a raw tree node.

Cmn
inline Boolean

Evaluates a boolean query against the current UiMediaScope from a CompositionLocalAccessorScope.

Cmn
inline Boolean

Evaluates a boolean query against the current UiMediaScope from a Modifier.Node.

Cmn
Modifier

Set a requested frame rate on Composable

Cmn
Modifier
Modifier.preferredFrameRate(
    frameRate: @FloatRange(from = 0.0, to = 360.0) Float
)

Set a requested frame rate on Composable

Cmn
Modifier
Modifier.sensitiveContent(isContentSensitive: Boolean)

This modifier hints that the composable renders sensitive content (i.e. username, password, credit card etc) on the screen, and the content should be protected during screen share in supported environments.

Cmn
Modifier

Creates a modifier that controls the drawing order for the children of the same layout parent.

Cmn

Top-level properties summary

ProvidableCompositionLocal<UiMediaScope>

A UiMediaScope provides information about the window environment and input devices, enabling adaptive layouts and behavior.

Cmn

Top-level functions

derivedMediaQuery

@ExperimentalMediaQueryApi
@Composable
fun derivedMediaQuery(query: UiMediaScope.() -> Boolean): State<Boolean>

Evaluates a boolean query against the current UiMediaScope, wrapped in a derivedStateOf.

Use this function for queries that involve frequently changing values, such as UiMediaScope.windowWidth or UiMediaScope.windowHeight. It ensures that compositions only recompose when the boolean result of the query changes, not on every small change to the underlying values (like a 1px size change).

For queries on stable properties, you can use the simpler mediaQuery function.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.ui.Modifier
import androidx.compose.ui.UiMediaScope.ViewingDistance
import androidx.compose.ui.derivedMediaQuery
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp

Box(Modifier.fillMaxSize().padding(top = 100.dp)) {
    val showDualPane by derivedMediaQuery { windowWidth >= 600.dp }
    val showNavigationRail by derivedMediaQuery {
        windowWidth >= 500.dp && viewingDistance != ViewingDistance.Near
    }

    Column(Modifier.fillMaxSize()) {
        Row(Modifier.weight(1f).fillMaxWidth()) {
            if (showNavigationRail) {
                // Show navigation rail
                Box(Modifier.width(150.dp).background(Color.Red).fillMaxHeight())
            }

            // Actual content
            Box(Modifier.weight(1f).background(Color.Yellow).fillMaxHeight())

            if (showDualPane) {
                // Split screen into 2 panes for additional content
                Box(Modifier.weight(1f).background(Color.Cyan).fillMaxHeight())
            }
        }

        if (!showNavigationRail && !showDualPane) {
            // Show bottom navigation
            Box(Modifier.background(Color.Blue).height(80.dp).fillMaxWidth())
        }
    }
}
Parameters
query: UiMediaScope.() -> Boolean

The condition to evaluate against the UiMediaScope.

Returns
State<Boolean>

A State holding the boolean result of the query. The state will only update when the evaluated result of the query changes.

mediaQuery

@ExperimentalMediaQueryApi
@Composable
fun mediaQuery(query: UiMediaScope.() -> Boolean): Boolean

Evaluates a boolean query against the current UiMediaScope.

Avoid reading properties marked with @FrequentlyChangingValue (such as UiMediaScope.windowWidth or UiMediaScope.windowHeight) inside the query block. Reading these properties will cause the composable to recompose on every frame during events such as window resizing, which can affect the performance.

For queries involving such frequently changing values, use derivedMediaQuery instead.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.material.Text
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.UiMediaScope.Posture
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.mediaQuery
import androidx.compose.ui.unit.dp

Column(Modifier.fillMaxSize()) {
    when {
        mediaQuery { windowPosture == Posture.Tabletop } -> {
            // Tabletop mode layout: Two rows separated by hinge
            Column(Modifier.fillMaxSize()) {
                Box(
                    Modifier.weight(1f).background(Color.Red).fillMaxWidth(),
                    contentAlignment = Alignment.Center,
                ) {
                    Text("Tabletop mode")
                }
                Box(
                    Modifier.height(20.dp).background(Color.Black).fillMaxWidth()
                ) // Hinge visualization
                Box(Modifier.weight(1f).background(Color.Blue).fillMaxWidth())
            }
        }
        mediaQuery { windowPosture == Posture.Book } -> {
            // Book mode layout: Two columns separated by hinge
            Row(Modifier.fillMaxSize()) {
                Box(
                    Modifier.weight(1f).background(Color.Red).fillMaxHeight(),
                    contentAlignment = Alignment.Center,
                ) {
                    Text("Book mode")
                }
                Box(
                    Modifier.width(20.dp).background(Color.Black).fillMaxHeight()
                ) // Hinge visualization
                Box(Modifier.weight(1f).background(Color.Blue).fillMaxHeight())
            }
        }
        else -> {
            // Flat mode
            Box(
                Modifier.background(Color.LightGray).fillMaxSize(),
                contentAlignment = Alignment.Center,
            ) {
                Text("Flat mode")
            }
        }
    }
}
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.style.Style
import androidx.compose.material.Button
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.UiMediaScope.PointerPrecision
import androidx.compose.ui.UiMediaScope.ViewingDistance
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.mediaQuery
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp

Column(Modifier.padding(top = 100.dp).padding(16.dp)) {
    val isTouchPrimary = mediaQuery { pointerPrecision == PointerPrecision.Coarse }
    val isUnreachable = mediaQuery { viewingDistance != ViewingDistance.Near }

    // Adjust button size for touch targets
    val adaptiveSize =
        when {
            isUnreachable -> DpSize(150.dp, 70.dp)
            isTouchPrimary -> DpSize(120.dp, 50.dp)
            else -> DpSize(100.dp, 40.dp)
        }

    // Adjust style for reachability
    val label = "Submit"
    val adaptiveLabel = if (isUnreachable) label.uppercase(getDefault()) else label

    Button(
        modifier =
            Modifier.clip(RoundedCornerShape(8.dp)).size(adaptiveSize).background(Color.Blue),
        onClick = {},
    ) {
        Text(text = adaptiveLabel, color = Color.White, style = TextStyle())
    }
}
Parameters
query: UiMediaScope.() -> Boolean

The condition to evaluate against the UiMediaScope.

Returns
Boolean

The boolean result of the query.

Extension functions

composed

fun Modifier.composed(
    inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
    factory: @Composable Modifier.() -> Modifier
): Modifier

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies. composed may be used to implement stateful modifiers that have instance-specific state for each modified element, allowing the same Modifier instance to be safely reused for multiple elements while maintaining element-specific state.

If inspectorInfo is specified this modifier will be visible to tools during development. Specify the name and arguments of the original modifier.

Example usage:

import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo

// let's create your own custom stateful modifier
fun Modifier.myColorModifier(color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myColorModifier"
                // specify a single argument as the value when the argument name is irrelevant
                value = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Dp

// let's create your own custom stateful modifier with multiple arguments
fun Modifier.myModifier(width: Dp, height: Dp, color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myModifier"
                // add name and value of each argument
                properties["width"] = width
                properties["height"] = height
                properties["color"] = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )

materialize must be called to create instance-specific modifiers if you are directly applying a Modifier to an element tree node.

composed

fun Modifier.composed(
    fullyQualifiedName: String,
    key1: Any?,
    inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
    factory: @Composable Modifier.() -> Modifier
): Modifier

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies. composed may be used to implement stateful modifiers that have instance-specific state for each modified element, allowing the same Modifier instance to be safely reused for multiple elements while maintaining element-specific state.

When keys are provided, composed produces a Modifier that will compare equals to another modifier constructed with the same keys in order to take advantage of caching and skipping optimizations. fullyQualifiedName should be the fully-qualified import name for your modifier factory function, e.g. com.example.myapp.ui.fancyPadding.

If inspectorInfo is specified this modifier will be visible to tools during development. Specify the name and arguments of the original modifier.

Example usage:

import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo

// let's create your own custom stateful modifier
fun Modifier.myColorModifier(color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myColorModifier"
                // specify a single argument as the value when the argument name is irrelevant
                value = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Dp

// let's create your own custom stateful modifier with multiple arguments
fun Modifier.myModifier(width: Dp, height: Dp, color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myModifier"
                // add name and value of each argument
                properties["width"] = width
                properties["height"] = height
                properties["color"] = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )

materialize must be called to create instance-specific modifiers if you are directly applying a Modifier to an element tree node.

composed

fun Modifier.composed(
    fullyQualifiedName: String,
    vararg keys: Any?,
    inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
    factory: @Composable Modifier.() -> Modifier
): Modifier

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies. composed may be used to implement stateful modifiers that have instance-specific state for each modified element, allowing the same Modifier instance to be safely reused for multiple elements while maintaining element-specific state.

When keys are provided, composed produces a Modifier that will compare equals to another modifier constructed with the same keys in order to take advantage of caching and skipping optimizations. fullyQualifiedName should be the fully-qualified import name for your modifier factory function, e.g. com.example.myapp.ui.fancyPadding.

If inspectorInfo is specified this modifier will be visible to tools during development. Specify the name and arguments of the original modifier.

Example usage:

import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo

// let's create your own custom stateful modifier
fun Modifier.myColorModifier(color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myColorModifier"
                // specify a single argument as the value when the argument name is irrelevant
                value = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Dp

// let's create your own custom stateful modifier with multiple arguments
fun Modifier.myModifier(width: Dp, height: Dp, color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myModifier"
                // add name and value of each argument
                properties["width"] = width
                properties["height"] = height
                properties["color"] = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )

materialize must be called to create instance-specific modifiers if you are directly applying a Modifier to an element tree node.

composed

fun Modifier.composed(
    fullyQualifiedName: String,
    key1: Any?,
    key2: Any?,
    inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
    factory: @Composable Modifier.() -> Modifier
): Modifier

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies. composed may be used to implement stateful modifiers that have instance-specific state for each modified element, allowing the same Modifier instance to be safely reused for multiple elements while maintaining element-specific state.

When keys are provided, composed produces a Modifier that will compare equals to another modifier constructed with the same keys in order to take advantage of caching and skipping optimizations. fullyQualifiedName should be the fully-qualified import name for your modifier factory function, e.g. com.example.myapp.ui.fancyPadding.

If inspectorInfo is specified this modifier will be visible to tools during development. Specify the name and arguments of the original modifier.

Example usage:

import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo

// let's create your own custom stateful modifier
fun Modifier.myColorModifier(color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myColorModifier"
                // specify a single argument as the value when the argument name is irrelevant
                value = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Dp

// let's create your own custom stateful modifier with multiple arguments
fun Modifier.myModifier(width: Dp, height: Dp, color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myModifier"
                // add name and value of each argument
                properties["width"] = width
                properties["height"] = height
                properties["color"] = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )

materialize must be called to create instance-specific modifiers if you are directly applying a Modifier to an element tree node.

composed

fun Modifier.composed(
    fullyQualifiedName: String,
    key1: Any?,
    key2: Any?,
    key3: Any?,
    inspectorInfo: InspectorInfo.() -> Unit = NoInspectorInfo,
    factory: @Composable Modifier.() -> Modifier
): Modifier

Declare a just-in-time composition of a Modifier that will be composed for each element it modifies. composed may be used to implement stateful modifiers that have instance-specific state for each modified element, allowing the same Modifier instance to be safely reused for multiple elements while maintaining element-specific state.

When keys are provided, composed produces a Modifier that will compare equals to another modifier constructed with the same keys in order to take advantage of caching and skipping optimizations. fullyQualifiedName should be the fully-qualified import name for your modifier factory function, e.g. com.example.myapp.ui.fancyPadding.

If inspectorInfo is specified this modifier will be visible to tools during development. Specify the name and arguments of the original modifier.

Example usage:

import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo

// let's create your own custom stateful modifier
fun Modifier.myColorModifier(color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myColorModifier"
                // specify a single argument as the value when the argument name is irrelevant
                value = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )
import androidx.compose.ui.Modifier
import androidx.compose.ui.composed
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.debugInspectorInfo
import androidx.compose.ui.unit.Dp

// let's create your own custom stateful modifier with multiple arguments
fun Modifier.myModifier(width: Dp, height: Dp, color: Color) =
    composed(
        // pass inspector information for debug
        inspectorInfo =
            debugInspectorInfo {
                // name should match the name of the modifier
                name = "myModifier"
                // add name and value of each argument
                properties["width"] = width
                properties["height"] = height
                properties["color"] = color
            },
        // pass your modifier implementation that resolved per modified element
        factory = {
            // add your modifier implementation here
            Modifier
        },
    )

materialize must be called to create instance-specific modifiers if you are directly applying a Modifier to an element tree node.

keepScreenOn

fun Modifier.keepScreenOn(): Modifier

A modifier that keeps the device screen on as long as it is part of the composition on supported platforms.

This is useful for scenarios where the user might not be interacting with the screen frequently but the content needs to remain visible, such as during video playback.

materialize

fun Composer.materialize(modifier: Modifier): Modifier

Materialize any instance-specific composed modifiers for applying to a raw tree node. Call right before setting the returned modifier on an emitted node. You almost certainly do not need to call this function directly.

mediaQuery

@ExperimentalMediaQueryApi
inline fun CompositionLocalAccessorScope.mediaQuery(query: UiMediaScope.() -> Boolean): Boolean

Evaluates a boolean query against the current UiMediaScope from a CompositionLocalAccessorScope.

If called within a snapshot-aware context, the specific property reads within the query will be tracked, and the scope will be invalidated when any of those properties change.

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.style.MutableStyleState
import androidx.compose.foundation.style.Style
import androidx.compose.foundation.style.hovered
import androidx.compose.foundation.style.pressed
import androidx.compose.foundation.style.styleable
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.UiMediaScope.PointerPrecision
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.mediaQuery
import androidx.compose.ui.unit.dp

// Create a styleable clickable box
@Composable
fun ClickableStyleableBox(
    onClick: () -> Unit,
    modifier: Modifier = Modifier,
    style: Style = Style,
) {
    val interactionSource = remember { MutableInteractionSource() }
    val styleState = remember { MutableStyleState(interactionSource) }
    Box(
        modifier =
            modifier
                .clickable(interactionSource = interactionSource, onClick = onClick)
                .styleable(styleState, style)
    )
}

ClickableStyleableBox(
    onClick = {},
    style = {
        background(Color.Green)

        // Dynamic size based on window Size
        if (mediaQuery { windowWidth > 600.dp && windowHeight > 400.dp }) {
            size(200.dp)
        } else {
            size(150.dp)
        }

        // Hover state for fine pointer input
        if (mediaQuery { pointerPrecision == PointerPrecision.Fine }) {
            hovered { background(Color.Yellow) }
        }
        pressed { background(Color.Red) }
    },
)
Parameters
query: UiMediaScope.() -> Boolean

A lambda expression with UiMediaScope as its receiver, representing the condition to check.

Returns
Boolean

The immediate boolean result of the query.

mediaQuery

@ExperimentalMediaQueryApi
inline fun CompositionLocalConsumerModifierNode.mediaQuery(query: UiMediaScope.() -> Boolean): Boolean

Evaluates a boolean query against the current UiMediaScope from a Modifier.Node.

This function is designed to be used within a Modifier.Node that implements CompositionLocalConsumerModifierNode.

If called within a snapshot-aware context like LayoutModifierNode.measure or DrawModifierNode.draw callbacks, the reads within the query will be tracked, and the scope will be invalidated when the properties change.

import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.runtime.Stable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.layout.Measurable
import androidx.compose.ui.layout.MeasureResult
import androidx.compose.ui.layout.MeasureScope
import androidx.compose.ui.mediaQuery
import androidx.compose.ui.node.CompositionLocalConsumerModifierNode
import androidx.compose.ui.node.LayoutModifierNode
import androidx.compose.ui.node.ModifierNodeElement
import androidx.compose.ui.unit.Constraints
import androidx.compose.ui.unit.constrainHeight
import androidx.compose.ui.unit.constrainWidth
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.offset

// Example of a custom padding modifier that uses [mediaQuery] within a [Modifier.Node].
class AdaptivePaddingNode :
    Modifier.Node(), LayoutModifierNode, CompositionLocalConsumerModifierNode {
    override fun MeasureScope.measure(
        measurable: Measurable,
        constraints: Constraints,
    ): MeasureResult {
        val isLargeScreen = mediaQuery { windowWidth > 600.dp && windowHeight > 400.dp }

        // Adjust padding or size based on the query result
        val extraPadding = if (isLargeScreen) 80.dp.roundToPx() else 16.dp.roundToPx()
        val totalPaddingOnAxis = 2 * extraPadding

        // Measure the content with added padding
        val placeable =
            measurable.measure(constraints.offset(-totalPaddingOnAxis, -totalPaddingOnAxis))

        val width = constraints.constrainWidth(placeable.width + totalPaddingOnAxis)
        val height = constraints.constrainHeight(placeable.height + totalPaddingOnAxis)

        return layout(width, height) { placeable.place(extraPadding, extraPadding) }
    }
}

class AdaptivePaddingElement : ModifierNodeElement<AdaptivePaddingNode>() {
    override fun create() = AdaptivePaddingNode()

    override fun update(node: AdaptivePaddingNode) {}

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

    override fun hashCode() = 0
}

@Stable fun Modifier.adaptivePadding(): Modifier = this.then(AdaptivePaddingElement())

Box(Modifier.adaptivePadding().background(Color.Blue).size(400.dp))
Parameters
query: UiMediaScope.() -> Boolean

A lambda expression with UiMediaScope as its receiver, representing the condition to check.

Returns
Boolean

The immediate boolean result of the query.

preferredFrameRate

fun Modifier.preferredFrameRate(frameRateCategory: FrameRateCategory): Modifier

Set a requested frame rate on Composable

You can set the preferred frame rate (frames per second) for a Composable using a frame rate category see: FrameRateCategory.

For increased frame rates, please consider using FrameRateCategory.High.

Keep in mind that the preferred frame rate affects the frame rate for the next frame, so use this method carefully. It's important to note that the preference is valid as long as the Composable is drawn.

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.material.Button
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.FrameRateCategory
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.preferredFrameRate
import androidx.compose.ui.unit.dp

var targetAlpha by remember { mutableFloatStateOf(1f) }
val context = LocalContext.current
val activity: Activity? = findOwner(context)
DisposableEffect(activity) {
    activity?.window?.frameRateBoostOnTouchEnabled = false
    onDispose { activity?.window?.frameRateBoostOnTouchEnabled = true }
}

val alpha by
    animateFloatAsState(targetValue = targetAlpha, animationSpec = tween(durationMillis = 5000))

Column(modifier = Modifier.size(300.dp)) {
    Button(
        onClick = { targetAlpha = if (targetAlpha == 1f) 0.2f else 1f },
        modifier =
            Modifier.testTag("frameRateTag")
                .background(LocalContentColor.current.copy(alpha = alpha)),
    ) {
        Text(
            text = "Click Me for alpha change with frame rate category High",
            color = LocalContentColor.current.copy(alpha = alpha),
            modifier = Modifier.preferredFrameRate(FrameRateCategory.High),
        )
    }
}
Parameters
frameRateCategory: FrameRateCategory

The preferred frame rate category the content should be rendered at.

See also
graphicsLayer

preferredFrameRate

fun Modifier.preferredFrameRate(
    frameRate: @FloatRange(from = 0.0, to = 360.0) Float
): Modifier

Set a requested frame rate on Composable

You can set the preferred frame rate (frames per second) for a Composable using a non-negative number. This API should only be used when a specific frame rate is needed for your Composable. For example, 24 or 30 for video play.

If multiple frame rates are requested, they will be aggregated to determine a feasible frame rate.

If you no longer want this modifier to influence the frame rate, clear the preference by setting it to 0.

Keep in mind that the preferred frame rate affects the frame rate for the next frame, so use this method carefully. It's important to note that the preference is valid as long as the Composable is drawn.

import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.animation.core.tween
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.size
import androidx.compose.material.Button
import androidx.compose.material.LocalContentColor
import androidx.compose.material.Text
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.testTag
import androidx.compose.ui.preferredFrameRate
import androidx.compose.ui.unit.dp

var targetAlpha by remember { mutableFloatStateOf(1f) }
val context = LocalContext.current
val activity: Activity? = findOwner(context)
DisposableEffect(activity) {
    activity?.window?.frameRateBoostOnTouchEnabled = false
    onDispose { activity?.window?.frameRateBoostOnTouchEnabled = true }
}

val alpha by
    animateFloatAsState(targetValue = targetAlpha, animationSpec = tween(durationMillis = 5000))

Column(modifier = Modifier.size(300.dp)) {
    Button(
        onClick = { targetAlpha = if (targetAlpha == 1f) 0.2f else 1f },
        modifier =
            Modifier.testTag("frameRateTag")
                .background(LocalContentColor.current.copy(alpha = alpha)),
    ) {
        Text(
            text = "Click Me for alpha change with 30 Hz frame rate",
            color = LocalContentColor.current.copy(alpha = alpha), // Adjust text alpha
            modifier = Modifier.preferredFrameRate(30f),
        )
    }
}
Parameters
frameRate: @FloatRange(from = 0.0, to = 360.0) Float

The preferred frame rate the content should be rendered at. Default value is 0.

See also
graphicsLayer

sensitiveContent

fun Modifier.sensitiveContent(isContentSensitive: Boolean = true): Modifier

This modifier hints that the composable renders sensitive content (i.e. username, password, credit card etc) on the screen, and the content should be protected during screen share in supported environments.

Parameters
isContentSensitive: Boolean = true

whether the content is sensitive or not. Defaults to true.

zIndex

fun Modifier.zIndex(zIndex: Float): Modifier

Creates a modifier that controls the drawing order for the children of the same layout parent. A child with larger zIndex will be drawn on top of all the children with smaller zIndex. When children have the same zIndex the original order in which the parent placed the children is used.

Note that if there would be multiple zIndex modifiers applied for the same layout the sum of their values will be used as the final zIndex. If no zIndex were applied for the layout then the default zIndex is 0.

import androidx.compose.foundation.layout.Box
import androidx.compose.material.Text
import androidx.compose.ui.Modifier
import androidx.compose.ui.zIndex

Box {
    Text("Drawn second", Modifier.zIndex(1f))
    Text("Drawn first")
}

Top-level properties

LocalUiMediaScope

@ExperimentalMediaQueryApi
val LocalUiMediaScopeProvidableCompositionLocal<UiMediaScope>

A UiMediaScope provides information about the window environment and input devices, enabling adaptive layouts and behavior. This CompositionLocal is the primary mechanism to access the scope within the composable tree.

It is typically provided at the root of an application. Accessing it without a provider will result in a runtime error.