androidx.xr.compose.subspace

Interfaces

SpatialBoxScope

Scope for the children of SpatialBox.

SpatialColumnScope

Scope for customizing the layout of children within a SpatialColumn.

SpatialExternalSurfaceScope

SpatialExternalSurfaceScope is a scoped environment that provides the Surface associated with a SpatialExternalSurface

SpatialRowScope

Scope for customizing the layout of children within a SpatialRow.

Classes

AnchorPolicy

Represents the anchoring behavior of a spatial object.

DragPolicy

Base Policy for motion behavior of spatial objects.

MovePolicy

Defines the movement policy for a spatial object.

ResizePolicy

Defines the resizing policy for a spatial object.

SceneCoreEntitySizeAdapter

The sizing strategy used by SceneCoreEntity to control and read the size of an entity.

StereoMode

Mode for SpatialExternalSurface display.

SurfaceProtection

Specifies if the Surface should be backed by android.hardware.HardwareBuffers with the USAGE_PROTECTED_CONTENT flag set.

Objects

SpatialCurvedRowDefaults

Contains the default values used by SpatialCurvedRow.

SpatialPanelDefaults

Contains default values used by spatial panels.

Annotations

ExperimentalSubspaceVolumeApi

Marks Subspace APIs that are experimental and likely to change or be removed in the future.

SubspaceComposable

Marks a composable function or other code element as intended for use within the context of SubspaceComposable functions.

Top-level functions summary

Unit
@Composable
@SubspaceComposable
<T : Entity> SceneCoreEntity(
    factory: () -> T,
    modifier: SubspaceModifier,
    update: (T) -> Unit,
    sizeAdapter: SceneCoreEntitySizeAdapter<T>?,
    content: @Composable @SubspaceComposable () -> Unit
)

A composable that attaches to a SceneCore entity and allow compose to size, position, reparent, add children, and apply modifiers to the entity.

Unit
@Composable
@SubspaceComposable
SpatialActivityPanel(
    intent: Intent,
    modifier: SubspaceModifier,
    shape: SpatialShape,
    dragPolicy: DragPolicy?,
    resizePolicy: ResizePolicy?
)

Creates a SpatialActivityPanel and launches an Activity within it.

Unit
@Composable
@SubspaceComposable
<T : View> SpatialAndroidViewPanel(
    factory: (Context) -> T,
    modifier: SubspaceModifier,
    update: (T) -> Unit,
    shape: SpatialShape,
    dragPolicy: DragPolicy?,
    resizePolicy: ResizePolicy?
)

Creates a SpatialAndroidViewPanel representing a 2D plane in 3D space where an Android View will be hosted.

Unit
@Composable
@SubspaceComposable
SpatialBox(
    modifier: SubspaceModifier,
    alignment: SpatialAlignment,
    propagateMinConstraints: Boolean,
    content: @Composable @SubspaceComposable SpatialBoxScope.() -> Unit
)

A layout composable that sizes itself to fit its content, subject to incoming constraints.

Unit
@Composable
@SubspaceComposable
SpatialColumn(
    modifier: SubspaceModifier,
    alignment: SpatialAlignment,
    verticalArrangement: SpatialArrangement.Vertical,
    content: @Composable @SubspaceComposable SpatialColumnScope.() -> Unit
)

A layout composable that arranges its children in a vertical sequence.

Unit
@Composable
@SubspaceComposable
SpatialCurvedRow(
    modifier: SubspaceModifier,
    alignment: SpatialAlignment,
    horizontalArrangement: SpatialArrangement.Horizontal,
    curveRadius: Dp,
    content: @Composable @SubspaceComposable SpatialRowScope.() -> Unit
)

A layout composable that arranges its children in a curved horizontal sequence.

Unit
@Composable
@SubspaceComposable
SpatialExternalSurface(
    stereoMode: StereoMode,
    modifier: SubspaceModifier,
    featheringEffect: SpatialFeatheringEffect,
    surfaceProtection: SurfaceProtection,
    dragPolicy: DragPolicy?,
    resizePolicy: ResizePolicy?,
    content: @Composable @SubspaceComposable SpatialExternalSurfaceScope.() -> Unit
)

A Composable that creates and owns an Android Surface into which the application can render stereo image content.

Unit

A composable that represents an empty space layout.

Unit
@Composable
@SubspaceComposable
SpatialMainPanel(
    modifier: SubspaceModifier,
    shape: SpatialShape,
    dragPolicy: DragPolicy?,
    resizePolicy: ResizePolicy?
)

A composable that renders the Activity's main window's 2D UI content, defined in androidx.activity.compose.setContent, as a panel in a Subspace.

Unit
@Composable
@SubspaceComposable
SpatialPanel(
    modifier: SubspaceModifier,
    shape: SpatialShape,
    dragPolicy: DragPolicy?,
    resizePolicy: ResizePolicy?,
    content: @Composable @UiComposable () -> Unit
)

Creates a SpatialPanel representing a 2D plane in 3D space in which an application can fill content.

Unit
@Composable
@SubspaceComposable
SpatialRow(
    modifier: SubspaceModifier,
    alignment: SpatialAlignment,
    horizontalArrangement: SpatialArrangement.Horizontal,
    content: @Composable @SubspaceComposable SpatialRowScope.() -> Unit
)

A layout composable that arranges its children in a horizontal sequence.

Unit

A composable that represents a 3D volume of space within which an application can fill content.

Top-level functions

SceneCoreEntity

@Composable
@SubspaceComposable
fun <T : Entity> SceneCoreEntity(
    factory: () -> T,
    modifier: SubspaceModifier = SubspaceModifier,
    update: (T) -> Unit = {},
    sizeAdapter: SceneCoreEntitySizeAdapter<T>? = null,
    content: @Composable @SubspaceComposable () -> Unit = {}
): Unit

A composable that attaches to a SceneCore entity and allow compose to size, position, reparent, add children, and apply modifiers to the entity.

Usage of this API requires the SceneCore dependency to be added. See https://developer.android.com/jetpack/androidx/releases/xr-scenecore

Parameters
factory: () -> T

the factory method for creating the SceneCore Entity.

modifier: SubspaceModifier = SubspaceModifier

the SubspaceModifier that will be applied to this node.

update: (T) -> Unit = {}

a callback to be invoked on recomposition to apply any state changes to the Entity. This will track snapshot state reads and call update when they change.

sizeAdapter: SceneCoreEntitySizeAdapter<T>? = null

an adapter that allows compose to integrate its layout size changes with the rendered entity size. This adapter implementation will likely be different for every entity and some SceneCore entities may not require sizing at all (this may be null).

content: @Composable @SubspaceComposable () -> Unit = {}

the children of this Entity.

See also
SceneCoreEntitySizeAdapter

for more information on how compose sizes SceneCore entities.

SpatialActivityPanel

@Composable
@SubspaceComposable
fun SpatialActivityPanel(
    intent: Intent,
    modifier: SubspaceModifier = SubspaceModifier,
    shape: SpatialShape = SpatialPanelDefaults.shape,
    dragPolicy: DragPolicy? = null,
    resizePolicy: ResizePolicy? = null
): Unit

Creates a SpatialActivityPanel and launches an Activity within it.

The only supported use case for this SpatialPanel is to launch activities that are a part of the same application.

Parameters
intent: Intent

The intent of an Activity to launch within this panel.

modifier: SubspaceModifier = SubspaceModifier

SubspaceModifiers to apply to the SpatialPanel.

shape: SpatialShape = SpatialPanelDefaults.shape

The shape of this Spatial Panel.

dragPolicy: DragPolicy? = null

An optional DragPolicy that defines the motion behavior of the SpatialPanel. This can be either a MovePolicy for free movement or an AnchorPolicy for anchoring to real-world surfaces. If a policy is provided, draggable UI controls will be shown, allowing the user to manipulate the panel in 3D space. If null, no motion behavior is applied.

resizePolicy: ResizePolicy? = null

An optional ResizePolicy configuration object that resizing behavior of this SpatialPanel. The draggable UI controls will be shown that allow the user to resize the element in 3D space. If null, there is no resize behavior applied to the element.

SpatialAndroidViewPanel

@Composable
@SubspaceComposable
fun <T : View> SpatialAndroidViewPanel(
    factory: (Context) -> T,
    modifier: SubspaceModifier = SubspaceModifier,
    update: (T) -> Unit = {},
    shape: SpatialShape = SpatialPanelDefaults.shape,
    dragPolicy: DragPolicy? = null,
    resizePolicy: ResizePolicy? = null
): Unit

Creates a SpatialAndroidViewPanel representing a 2D plane in 3D space where an Android View will be hosted.

The presented View is obtained from factory. The factory block will be called exactly once to obtain the View being composed into this panel, and it is also guaranteed to be executed on the main thread. Therefore, in addition to creating the View, the factory block can also be used to perform one-off initializations and View constant properties' setting. The factory inside of the constructor is used to avoid the need to pass the context to the factory. There is one View for every SpatialAndroidViewPanel instance and it is reused across recompositions. This View is shown effectively in isolation and does not interact directly with the other composable's that surround it. The update block can run multiple times (on the UI thread as well) due to recomposition, and it is the right place to set the new properties. Note that the block will also run once right after the factory block completes. SpatialAndroidViewPanel will clip the view content to fit the panel.

Parameters
<T : View>

The type of the Android View to be created.

factory: (Context) -> T

A lambda that creates an instance of the Android View T.

modifier: SubspaceModifier = SubspaceModifier

SubspaceModifiers to apply to the SpatialPanel.

update: (T) -> Unit = {}

A lambda that allows updating the created Android View T.

shape: SpatialShape = SpatialPanelDefaults.shape

The shape of this Spatial Panel.

dragPolicy: DragPolicy? = null

An optional DragPolicy that defines the motion behavior of the SpatialPanel. This can be either a MovePolicy for free movement or an AnchorPolicy for anchoring to real-world surfaces. If a policy is provided, draggable UI controls will be shown, allowing the user to manipulate the panel in 3D space. If null, no motion behavior is applied.

resizePolicy: ResizePolicy? = null

An optional ResizePolicy configuration object that resizing behavior of this SpatialPanel. The draggable UI controls will be shown that allow the user to resize the element in 3D space. If null, there is no resize behavior applied to the element.

SpatialBox

@Composable
@SubspaceComposable
fun SpatialBox(
    modifier: SubspaceModifier = SubspaceModifier,
    alignment: SpatialAlignment = SpatialAlignment.Center,
    propagateMinConstraints: Boolean = false,
    content: @Composable @SubspaceComposable SpatialBoxScope.() -> Unit
): Unit

A layout composable that sizes itself to fit its content, subject to incoming constraints.

A layout composable with content. The SpatialBox will size itself to fit the content, subject to the incoming constraints. When children are smaller than the parent, by default they will be positioned inside the SpatialBox according to the alignment. For individually specifying the alignments of the children layouts, use the SpatialBoxScope.align modifier. By default, the content will be measured without the SpatialBox's incoming min constraints. If propagateMinConstraints is set to true, the min size set on the SpatialBox will also be applied to the content.

Note: If the content has multiple children, they might overlap depending on their positioning.

Parameters
modifier: SubspaceModifier = SubspaceModifier

The modifier to be applied to the layout.

alignment: SpatialAlignment = SpatialAlignment.Center

The default alignment of children within the SpatialBox.

propagateMinConstraints: Boolean = false

Whether the incoming min constraints should be passed to content.

content: @Composable @SubspaceComposable SpatialBoxScope.() -> Unit

The content of the SpatialBox.

SpatialColumn

@Composable
@SubspaceComposable
fun SpatialColumn(
    modifier: SubspaceModifier = SubspaceModifier,
    alignment: SpatialAlignment = SpatialAlignment.Center,
    verticalArrangement: SpatialArrangement.Vertical = SpatialArrangement.Center,
    content: @Composable @SubspaceComposable SpatialColumnScope.() -> Unit
): Unit

A layout composable that arranges its children in a vertical sequence.

For arranging children horizontally, see SpatialRow.

Parameters
modifier: SubspaceModifier = SubspaceModifier

Modifiers to apply to the layout.

alignment: SpatialAlignment = SpatialAlignment.Center

The default alignment for child elements within the column.

verticalArrangement: SpatialArrangement.Vertical = SpatialArrangement.Center

The vertical arrangement of the children.

content: @Composable @SubspaceComposable SpatialColumnScope.() -> Unit

The composable content to be laid out vertically.

SpatialCurvedRow

@Composable
@SubspaceComposable
fun SpatialCurvedRow(
    modifier: SubspaceModifier = SubspaceModifier,
    alignment: SpatialAlignment = SpatialAlignment.Center,
    horizontalArrangement: SpatialArrangement.Horizontal = SpatialArrangement.Center,
    curveRadius: Dp = SpatialCurvedRowDefaults.curveRadius,
    content: @Composable @SubspaceComposable SpatialRowScope.() -> Unit
): Unit

A layout composable that arranges its children in a curved horizontal sequence.

Parameters
modifier: SubspaceModifier = SubspaceModifier

Appearance modifiers to apply to this Composable.

alignment: SpatialAlignment = SpatialAlignment.Center

The default alignment for child elements within the row.

horizontalArrangement: SpatialArrangement.Horizontal = SpatialArrangement.Center

The horizontal arrangement of the children.

curveRadius: Dp = SpatialCurvedRowDefaults.curveRadius

Defines the curve of the row by specifying its radius in Dp. A larger radius creates a gentler curve (less curvature), while a smaller positive radius results in a sharper curve (more curvature). Using Dp.Infinity or a non-positive value (zero or negative) makes the row straight. When curved, row items are angled to follow the curve's path. This value is the radial distance in the polar coordinate system.

content: @Composable @SubspaceComposable SpatialRowScope.() -> Unit

The composable content to be laid out horizontally in the row.

SpatialExternalSurface

@Composable
@SubspaceComposable
fun SpatialExternalSurface(
    stereoMode: StereoMode,
    modifier: SubspaceModifier = SubspaceModifier,
    featheringEffect: SpatialFeatheringEffect = ZeroFeatheringEffect,
    surfaceProtection: SurfaceProtection = SurfaceProtection.None,
    dragPolicy: DragPolicy? = null,
    resizePolicy: ResizePolicy? = null,
    content: @Composable @SubspaceComposable SpatialExternalSurfaceScope.() -> Unit
): Unit

A Composable that creates and owns an Android Surface into which the application can render stereo image content. This can be thought of as the spatial equivalent of AndroidExternalSurface. This Surface is texture mapped to the canvas, and if a stereoscopic StereoMode is specified, then the User will see left and right eye content mapped to the appropriate display. Width and height will default to 400 pixels if it is not specified using size modifiers.

Note that this Surface does not capture input events. It is also not currently possible to synchronize StereoMode changes with application rendering or video decoding. This composable currently cannot render in front of other panels, so dragPolicy usage is not recommended if there are other panels in the layout, aside from the content block of this Composable.

Playing certain content will require the proper SurfaceProtection. This is mainly used to protect DRM video content.

Parameters
stereoMode: StereoMode

The StereoMode which describes how parts of the surface are displayed to the user's eyes. This will affect how the content is interpreted and displayed on the surface.

modifier: SubspaceModifier = SubspaceModifier

SubspaceModifiers to apply to the SpatialSurfacePanel.

featheringEffect: SpatialFeatheringEffect = ZeroFeatheringEffect

A SpatialFeatheringEffect to apply to to canvas of the surface exposed from SpatialExternalSurfaceScope.onSurfaceCreated.

surfaceProtection: SurfaceProtection = SurfaceProtection.None

Sets the Surface's content protection. Use this to redact content in screen recordings. Setting this to SurfaceProtection.Protected is required if decoding DRM media content.

dragPolicy: DragPolicy? = null

An optional DragPolicy that defines the motion behavior of the SpatialPanel. This can be either a MovePolicy for free movement or an AnchorPolicy for anchoring to real-world surfaces. If a policy is provided, draggable UI controls will be shown, allowing the user to manipulate the panel in 3D space. If null, no motion behavior is applied.

resizePolicy: ResizePolicy? = null

An optional ResizePolicy configuration object that resizing behavior of this SpatialPanel. The draggable UI controls will be shown that allow the user to resize the element in 3D space. If null, there is no resize behavior applied to the element.

content: @Composable @SubspaceComposable SpatialExternalSurfaceScope.() -> Unit

Content block where the surface can be accessed using SpatialExternalSurfaceScope.onSurfaceCreated. Composable content will be rendered over the Surface canvas. If using StereoMode.SideBySide or StereoMode.TopBottom, it is recommended to offset Composable content far enough to avoid depth perception issues.

SpatialLayoutSpacer

@Composable
@SubspaceComposable
fun SpatialLayoutSpacer(modifier: SubspaceModifier = SubspaceModifier): Unit

A composable that represents an empty space layout. Its size can be controlled using modifiers like SubspaceModifier.width, SubspaceModifier.height, etc.

Parameters
modifier: SubspaceModifier = SubspaceModifier

Modifiers to apply to the spacer.

SpatialMainPanel

@Composable
@SubspaceComposable
fun SpatialMainPanel(
    modifier: SubspaceModifier = SubspaceModifier,
    shape: SpatialShape = SpatialPanelDefaults.shape,
    dragPolicy: DragPolicy? = null,
    resizePolicy: ResizePolicy? = null
): Unit

A composable that renders the Activity's main window's 2D UI content, defined in androidx.activity.compose.setContent, as a panel in a Subspace.

This composable acts as the bridge between the traditional 2D Android UI hierarchy and the 3D Subspace environment. Unlike SpatialPanel, which renders its own specific composable content, SpatialMainPanel takes the entire view hierarchy from the Activity's main window and presents it on a movable, resizable panel in the Compose for XR's Spatial Scene Graph.

For the main window to be visible when androidx.xr.compose.spatial.Subspace is present in the UI hierarchy, a SpatialMainPanel must be included in the Subspace composition. If it is not composed, the underlying main panel entity is disabled by default. When SpatialMainPanel is removed from the composition, it will again be disable (hidden).

How It Works

SpatialMainPanel is backed by a single shared instance that will move to the main content to its active usage. When the main content panel moves inside the composition, its state moves with it regardless of whether it is in a MovableContent block or not. Components that depend on the main panel's state (such as androidx.xr.compose.spatial.Orbiter), will always access a single deterministic instance of the panel.

Note: It is crucial to ensure that only one SpatialMainPanel is active (composed) at any given time. The underlying system is designed around a single main panel instance, and having multiple active instances can lead to undefined behavior.

The size of the panel in the Subspace is controlled by the standard Compose layout system, driven by the SubspaceModifier applied to it. Modifiers like SubspaceModifier.width directly dictate the panel's dimensions, following the same measurement and layout rules as other SubspaceComposable. To ensure stability, if the panel's layout size results in a width or height of zero, it will be automatically disabled to prevent crashes.

Manifest Configuration

This panel requires the following specific configuration in the AndroidManifest.xml on the base activity for proper sizing and resizing behavior. Without it, resizing the main panel will cause a crash.

<activity android:configChanges="orientation|screenSize|screenLayout|smallestScreenSize">
...
</activity>
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.xr.compose.spatial.ApplicationSubspace
import androidx.xr.compose.subspace.SpatialMainPanel
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.SpatialRow

@Composable
fun MainPanelContent() {
    Text("Main panel")
}

@Composable
fun AppContent() {
    // 2D Content rendered to the main panel.
    MainPanelContent()

    // Spatial content rendered in full space mode.
    ApplicationSubspace {
        SpatialRow {
            SpatialPanel { Text("Spatial panel") }
            SpatialMainPanel()
        }
    }
}
Parameters
modifier: SubspaceModifier = SubspaceModifier

The SubspaceModifier to be applied to this panel, controlling its layout, size, and position within the parent.

shape: SpatialShape = SpatialPanelDefaults.shape

The shape of this Spatial Panel.

dragPolicy: DragPolicy? = null

An optional DragPolicy that defines the motion behavior of the SpatialPanel. This can be either a MovePolicy for free movement or an AnchorPolicy for anchoring to real-world surfaces. If a policy is provided, draggable UI controls will be shown, allowing the user to manipulate the panel in 3D space. If null, no motion behavior is applied.

resizePolicy: ResizePolicy? = null

An optional ResizePolicy configuration object that resizing behavior of this SpatialPanel. The draggable UI controls will be shown that allow the user to resize the element in 3D space. If null, there is no resize behavior applied to the element.

SpatialPanel

@Composable
@SubspaceComposable
fun SpatialPanel(
    modifier: SubspaceModifier = SubspaceModifier,
    shape: SpatialShape = SpatialPanelDefaults.shape,
    dragPolicy: DragPolicy? = null,
    resizePolicy: ResizePolicy? = null,
    content: @Composable @UiComposable () -> Unit
): Unit

Creates a SpatialPanel representing a 2D plane in 3D space in which an application can fill content.

Parameters
modifier: SubspaceModifier = SubspaceModifier

SubspaceModifiers to apply to the SpatialPanel.

shape: SpatialShape = SpatialPanelDefaults.shape

The shape of this Spatial Panel.

dragPolicy: DragPolicy? = null

An optional DragPolicy that defines the motion behavior of the SpatialPanel. This can be either a MovePolicy for free movement or an AnchorPolicy for anchoring to real-world surfaces. If a policy is provided, draggable UI controls will be shown, allowing the user to manipulate the panel in 3D space. If null, no motion behavior is applied.

resizePolicy: ResizePolicy? = null

An optional ResizePolicy that defines the resizing behavior of this SpatialPanel. If a policy is provided, resize UI controls will be shown, allowing the user to resize the element in 3D space. If null, no resize behavior is applied to the element.

content: @Composable @UiComposable () -> Unit

The composable content to render within the SpatialPanel.

SpatialRow

@Composable
@SubspaceComposable
fun SpatialRow(
    modifier: SubspaceModifier = SubspaceModifier,
    alignment: SpatialAlignment = SpatialAlignment.Center,
    horizontalArrangement: SpatialArrangement.Horizontal = SpatialArrangement.Center,
    content: @Composable @SubspaceComposable SpatialRowScope.() -> Unit
): Unit

A layout composable that arranges its children in a horizontal sequence. For arranging children vertically, see SpatialColumn.

Parameters
modifier: SubspaceModifier = SubspaceModifier

Appearance modifiers to apply to this Composable.

alignment: SpatialAlignment = SpatialAlignment.Center

The default alignment for child elements within the row.

horizontalArrangement: SpatialArrangement.Horizontal = SpatialArrangement.Center

The horizontal arrangement of the children.

content: @Composable @SubspaceComposable SpatialRowScope.() -> Unit

The composable content to be laid out horizontally in the row.

@Composable
@SubspaceComposable
@ExperimentalSubspaceVolumeApi
fun Volume(
    modifier: SubspaceModifier = SubspaceModifier,
    onVolumeEntity: (Entity) -> Unit
): Unit

A composable that represents a 3D volume of space within which an application can fill content.

This composable provides a Entity through the onVolumeEntity lambda, allowing the caller to attach child Jetpack XR Entities to it.

Parameters
modifier: SubspaceModifier = SubspaceModifier

SubspaceModifiers to apply to the Volume.

onVolumeEntity: (Entity) -> Unit

A lambda function that will be invoked when the Entity becomes available.