Jetpack Compose for XR
Latest Update | Stable Release | Release Candidate | Beta Release | Alpha Release |
---|---|---|---|---|
May 7, 2025 | - | - | - | 1.0.0-alpha04 |
Declaring dependencies
To add a dependency on XR compose, you must add the Google Maven repository to your project. Read Google's Maven repository for more information.
Add the dependencies for the artifacts you need in the build.gradle
file for
your app or module:
Groovy
dependencies { implementation "androidx.xr.compose:compose:1.0.0-alpha04" // Use to write unit tests testImplementation "androidx.xr.compose:compose-testing:1.0.0-alpha04" }
Kotlin
dependencies { implementation("androidx.xr.compose:compose:1.0.0-alpha04") // Use to write unit tests testImplementation("androidx.xr.compose:compose-testing:1.0.0-alpha04") }
For more information about dependencies, see Add build dependencies.
Feedback
Your feedback helps make Jetpack better. Let us know if you discover new issues or have ideas for improving this library. Please take a look at the existing issues in this library before you create a new one. You can add your vote to an existing issue by clicking the star button.
See the Issue Tracker documentation for more information.
Version 1.0
Version 1.0.0-alpha04
May 7, 2025
androidx.xr.compose:compose:1.0.0-alpha04
and androidx.xr.compose:compose-testing:1.0.0-alpha04
are released. Version 1.0.0-alpha04 contains these commits.
New Features
- Added
CompositionLocalConsumerSubspaceModifierNode
interface to allow customSubspaceModifier
types to access composition local values. - Added a new
SpatialPanel
API that follows the composeAndroidView
implementation style and deprecates the previousViewBased SpatialPanel
. - Added
VolumeConstraints.Unbounded
companion object which represents unbounded constraints. - Added
SubspaceModifier.onPointSourceParams
to allow a spatialized audio source. - A public
ApplicationSubspace
has been added, offering optionalVolumeConstraints
to define a 3D area where the app can render spatial content. By default, if no constraints are specified, the Subspace will be bounded by theSpatialUser
's current field of view in width and height. Users can provide constraints to be used if the field of view cannot be determined. Otherwise, the default field of view width and height values are used. - Added
SpatialExternalSurface
, which can be used to render stereoscopic content.SpatialExternalSurface
is customizable with modifiers (except alpha), and an edge feathering effect. - Added a new
pointerHoverIcon
Subspace Modifier that allows users to set the icon for the spatial pointer.
API Changes
- Removed
RequiresApi(34)
restriction on all Jetpack XR packages. This restriction was redundant as Jetpack XR is currently only available on devices with API level 34+. (Iae0f8) - Projects released with Kotlin 2.0 require KGP 2.0.0 or newer to be consumed. (Idb6b5)
- Back handling will now work on spatial panels without embedded activities. For back handling to work you need to specify
android:enableOnBackInvokedCallback="true"
in the android manifest. - Backhandling will now work on spatial dialogs. For backhandling to work you need to specify
android:enableOnBackInvokedCallback="true"
in the android manifest. - Compose-based and View-based
SpatialPanel
s can now size themselves based on their contents. - Developers may now set their own custom
SpatialElevationLevel
values and are not limited to the predefined levels. - Orbiter elevation level may now be customized via the
elevation
parameter. - Subspace can now be bounded by the
SpatialUser
's field of view in width and height by default. If the field of view cannot be determined, the default field of view width and height values are used. - Added new callbacks
onMoveStart
andonMoveEnd
to theMovable
modifier. TheonMoveStart
andonMoveEnd
callbacks are called when the user starts and ends moving a subspace composable with the movable modifier. - The
name
parameter has been removed from spatial APIs such asSpatialRow
andSpatialPanel
. For debugging spatial compose trees useSubspaceModifier.testTag
instead. - Removed an unsupported overload of
SpatialPopup
that only hasspatialElevationLevel
andcontent
. Please use the interface that supportsonDimissRequest
. - The
onPoseChange
callback from the Movable modifier has been removed. UseonMove
instead. SubspaceModifiers
will no longer apply their effects if they are detached or currently detaching.- The existing
SpatialRow
API has been split intoSpatialRow
andSpatialCurvedRow
. If previously usingSpatialRow
'scurveRadius
parameter, useSpatialCurvedRow
now instead which offers the same behavior. MainPanel
andActivityPanel
no longer have title bars when run on a similarly recent system image.- Alpha and scale modifiers are now stackable and will multiply their values for the final applied alpha or scale value.
- The
onPoseChange
callback from the Movable modifier has been optimized to perform smoother pose movement. - The movable and resizable modifiers will now perform their callbacks on the main thread to ensure that state changes will trigger recomposition.
- Added state observation to the layout and measure phases to ensure that state changes in
SubspaceLayout
will trigger relayout. - Optimized modifier chain updates to better reuse existing modifiers.
Bug Fixes
- Stopped scrimming when a
SpatialDialog
is shown. (Ic4594) - Relayout requests made while modifier nodes are detached will now be ignored.
- Removed relayout phases triggered by Movable and Resizable modifiers.
- Fixed a crash in
MainPanel()
composable that occurred when either dimension was set to zero, either directly or during a layout calculation, e.g., aSpatialRow/SpatialColumn
calculation. The panel will now be hidden instead. Note that this fix specifically addresses crashes during the layout phase; resizing the panel to zero via user interaction will be handled separately. The hidden panel lacks UI affordances. - Fixed issue with
maintainAspectRatio
from the resizable modifier. The aspect ratio should be kept now. - Fixed an issue with nested Subspaces where they would be incorrectly positioned for a single frame.
- Fixed issue where rounded corners were sometimes not applied when they should be.
NestedSubspaces
will no longer appear for one frame in the wrong location.
Version 1.0.0-alpha03
February 26, 2025
androidx.xr.compose:compose:1.0.0-alpha03
and androidx.xr.compose:compose-testing:1.0.0-alpha03
are released with no notable changes since the last alpha. Version 1.0.0-alpha03 contains these commits
Version 1.0.0-alpha02
February 12, 2025
androidx.xr.compose:compose:1.0.0-alpha02
and androidx.xr.compose:compose-testing:1.0.0-alpha02
are released. Version 1.0.0-alpha02 contains these commits.
New Features
- The Activity Panel can now scrim its content when a Spatial Dialog is activated.
- The
Orbiter
API is now usable inSubspaceComposable
contexts and will attach Orbiters to their nearestSubspaceLayout
-based composable parent. - Introduced
LayoutCoordinatesAwareModifierNode
to allow custom positioning-based modifiers. - Added attach/detach lifecycle methods to
SubspaceModifier.Node
. - Added
scaleWithDistance
to the movable modifier. WhenscaleWithDistance
is enabled, the subspace element moved will grow or shrink. It will also maintain any explicit scale that it had before movement.
API Changes
- Removed
SessionCallbackProvider
in favor ofSpatialCapabilities
.
Other changes
- Reduced
minSDK
to 24. All Jetpack XR APIs continue to require API 34 at runtime. Orbiter
EdgeOffset.inner
,EdgeOffset.outer
, andEdgeOffset.overlap
constructors are no longer@Composable
methods, which allows them to be used in non-composable contexts.- Update Spatial Elevation Levels to match the latest UX spec.
- Implement
SubspaceSemanticsInfo
interface intoMeasurableLayout
. - Renamed
SubspaceModifierElement
toSubspaceModifierNodeElement
.
Bug fixes
- Fixes to stabilize
SubspaceModifier
ordering.SubspaceModifier
should behave more reliably. Offset, rotate, scale, movable, and resizable modifier should now be usable in any order.
Version 1.0.0-alpha01
December 12, 2024
androidx.xr.compose:compose-*1.0.0-alpha01
is released.
Features of Initial Release
Initial developer release of Jetpack Compose for XR. Use familiar Compose concepts such as rows and columns to create spatial UI layouts in XR, whether you're porting an existing 2D app to XR or creating a new XR app from scratch. This library provides subspace and spatial composables: such as spatial panels and orbiters, which let you place your existing 2D Compose or Views-based UI in a spatial layout. It introduces the Volume subspace composable, which allows you to place SceneCore entities, such as 3D models, relative to your UI. Learn more in this developer guide:
Subspace
: This composable can be placed anywhere within your app’s UI hierarchy, allowing you to maintain layouts for 2D and spatial UI without losing context between files. This makes it easier to share things like existing app architecture between XR and other form factors without needing to hoist state through your whole UI tree or re-architect your app.SpatialPanel: A spatial panel is a subspace composable that lets you display app content–for example, you could display video playback, still images, or any other content in a spatial panel.
Orbiter: An orbiter is a spatial UI component. It's designed to be attached to a corresponding spatial panel, and contains navigation and contextual action items related to that spatial panel. For example, if you've created a spatial panel to display video content, you could add video playback controls inside an orbiter.
Volume: Place SceneCore entities, such as 3D models, relative to your UI.
Spatial Layout: You can create multiple spatial panels and place them within a Spatial Layout using
SpatialRow
,SpatialColumn
,SpatialBox
, andSpatialLayoutSpacer
. UseSubspaceModifier
s to customize your layout.Spatial UI components: These elements can be reused in your 2D UI, and their spatial attributes will only be visible when spatial capabilities are enabled.
SpatialDialog
: Panel will push slightly back in z-depth to display an elevated dialog.SpatialPopUp
: Panel will push slightly back in z-depth to display an elevated popupSpatialElevation
:SpatialElevationLevel
can be set to add elevation.
SpatialCapabilities: Spatial capabilities can change as users interact with your app or the system, or can even be changed by your app itself—for example, moving into Home Space or Full Space. To avoid issues, your app needs to check for
LocalSpatialCapabilities.current
to determine which APIs are supported in the current environment.isSpatialUiEnabled
: Spatial UI elements (e.g. SpatialPanel)isContent3dEnabled
: 3D objectsisAppEnvironmentEnabled
: The environmentisPassthroughControlEnabled
: Whether or not the application can control the passthrough stateisSpatialAudioEnabled
: Spatial audio
Known Issues
- Currently a minSDK of 30 is required to use Jetpack Compose for XR. As a workaround you may add the following manifest entry
<uses-sdk tools:overrideLibrary="androidx.xr.scenecore, androidx.xr.compose"/>
to be able to build and run with a minSDK of 23. - Jetpack XR apps currently require requesting
android.permission.SCENE_UNDERSTANDING
permission in the AndroidManifest. - When an app launches directly into Full Space using the
PROPERTY_XR_ACTIVITY_START_MODE
property in their manifest, Activities/Applications are initially opened in Home Space before transitioning into Full Space. - glTFs in Volume Composables may initially flicker at the wrong location.
- Using a SpatialDialog in a panel that has been moved significantly will push the content in the wrong direction.