Start native apps faster with the Composables CLI ->
Function

movable

Configures this subspace element to be interactive and movable.

movable

Source set: Android
public fun SubspaceModifier.movable(
    enabled: Boolean = true,
    movePolicy: MovePolicy = MovePolicy.default(),
): SubspaceModifier

Configures this subspace element to be interactive and movable.

When this modifier is present and enabled, draggable UI controls will be shown that allow the user to move the element in 3D space. The specific behavior of this movement—such as whether the system automatically applies the transformation, leaves it to the developer, or anchors it to physical surfaces—is defined by the provided MovePolicy. Input events used for moving in this way are consumed.

There are some limitations that should be considered when using this modifier: 1) the draggable UI controls of nested composables using the movable modifier may conflict with each other. 2) Attaching multiple movable modifiers with auto-applying policies (like MovePolicy.default) to the same element will compound the movement distance, since each modifier independently applies the drag offset upon release.

@sample androidx.xr.compose.samples.BasicMovableSample @sample androidx.xr.compose.samples.CustomMovableSample

Parameters

enabled true if this composable should be movable. Setting this to false will remove the interactable affordance associated with the content. Disabling the modifier after movement keeps the composable at its last dragged position. Removing the modifier entirely resets the composable to its original layout position.
movePolicy The MovePolicy that dictates how movement transformations are calculated and applied. Defaults to MovePolicy.default.

movable

Deprecated

This signature is deprecated. Use movable with MovePolicy.custom instead.

Source set: Android
public fun SubspaceModifier.movable(
    enabled: Boolean = true,
    scaleWithDistance: Boolean = true,
    onMove: ((SpatialMoveEvent) -> Unit),
): SubspaceModifier

Configures this subspace element to accept move events and report the calculated pose updates via a callback, without automatically applying a resulting transformation.

When the movable modifier is present and enabled, draggable UI controls will be shown that allow the user to move the element in 3D space. This modifier enables custom behavior for movement of the content. The system calculates the target Pose based on input, but does not automatically apply it to the associated layout. The developer is responsible for consuming the onMove event and applying the result. (e.g., by updating a state backed by SubspaceModifier.offset)

There are some limitations that should be considered when using this modifier: 1) the draggable UI controls of nested composables using the transformingMovable modifier and movable modifier may conflict with each other, 2) It cannot be used with the following composables androidx.xr.compose.subspace.SpatialExternalSurfaceHemisphere and androidx.xr.compose.subspace.SpatialExternalSurfaceSphere due to their similarity with the system environment and not having any layout size, 3) If this element has animations that affect its layout properties (e.g., offset), these animations should be stopped when a move gesture starts (detected via the onMove callback with SpatialMoveEventType.Start) to prevent rendering jitter, and can be resumed when the gesture ends (SpatialMoveEventType.End).

Parameters

enabled true if this composable should be movable. Setting this to false will remove the interactable affordance associated with the content. Disabling the modifier after movement keeps the composable at its last dragged position. Removing the modifier entirely resets the composable to its original layout position.
scaleWithDistance true if this composable should scale in size when moved in depth. When enabled, the subspace element will grow if pushed away from the user or shrink when pulled toward the user in order to maintain the interact-ability and legibility of the panel. Scaling with distance respects other transformations applied to this layout.
onMove callback invoked continuously during the interaction that receives a SpatialMoveEvent containing the calculated target pose, scale, and size. The pose contained in this event is the sum of all previous events in the move gesture. The receiver MUST use this data to update the element's external state to reflect movement.

movable

Deprecated

This signature is deprecated. The movement behavior is now configured via MovePolicy. For default system-handled movement, use movable(movePolicy = MovePolicy.default(...)). For custom movement where you manually apply the resulting pose, use movable(movePolicy = MovePolicy.custom(...)).

Source set: Android
public fun SubspaceModifier.movable(
    enabled: Boolean = true,
    stickyPose: Boolean = false,
    scaleWithDistance: Boolean = true,
    onMoveStart: ((SpatialMoveEvent) -> Unit)? = null,
    onMoveEnd: ((SpatialMoveEvent) -> Unit)? = null,
    onMove: ((SpatialMoveEvent) -> Boolean)? = null,
): SubspaceModifier

When the movable modifier is present and enabled, draggable UI controls will be shown that allow the user to move the element in 3D space.

There are some limitations that should be considered when using this modifier: 1) the draggable UI controls of nested composables using the movable modifier may conflict with each other, 2) when attaching multiple movable modifiers that handle movement internally, the movement effect will be compounded.

Parameters

enabled true if this composable should be movable.
stickyPose if enabled, the user specified position will be retained when the modifier is disabled or removed.
scaleWithDistance true if this composable should scale in size when moved in depth. When this scaleWithDistance is enabled, the subspace element moved will grow or shrink. It will also maintain any explicit scale that it had before movement.
onMoveStart a callback to process the start of a move event. This will only be called if enabled is true.
onMoveEnd a callback to process the end of a move event. This will only be called if enabled is true.
onMove a callback to process the pose change during movement, with translation in pixels. This will only be called if enabled is true. If the callback returns false the default behavior of moving this composable's subspace hierarchy will be executed. If it returns true, it is the responsibility of the callback to process the event.

Last updated: