1. Antes de comenzar
Qué aprenderás
- Las experiencias del usuario únicas que hace posibles el factor de forma de realidad extendida
- Los aspectos básicos de cómo se pueden adaptar las apps para aprovechar al máximo su ejecución en auriculares de Android XR usando elementos componibles proporcionados por la biblioteca de realidad extendida de Jetpack Compose
- Cómo usar los elementos de la IU proporcionados por la biblioteca de realidad extendida de Compose
- Dónde obtener más información sobre la compilación de apps para Android XR
Qué no es este codelab
- Una guía para compilar apps para Android XR sin usar Compose. Consulta Cómo desarrollar una IU de apps para Android basadas en vistas.
- Una guía para compilar apps con Unity o con OpenXR para Android XR. Consulta Cómo desarrollar con Unity para Android XR y Cómo desarrollar con OpenXR.
Requisitos
- Versión preliminar de Android Studio
- Una computadora con capacidad para ejecutar el emulador de Android XR
- Experiencia con Kotlin y Jetpack Compose, por ejemplo, haber completado el curso Aspectos básicos de Android con Compose
- Experiencia en la creación de dispositivos virtuales de Android y ejecución de apps en ellos
Qué compilarás
En este codelab, mejorarás una app básica con una única pantalla para ofrecer una experiencia del usuario inmersiva a través de Android XR.
Punto de partida | Resultado final |
2. Prepárate
Obtén el código
- El código de este codelab se puede encontrar en el directorio
xr-fundamentals
dentro del repositorioxr-codelabs
de GitHub. Para clonar el repositorio, ejecuta el siguiente comando:
git clone https://github.com/android/xr-codelabs.git
- También tienes la opción de descargar el repositorio como archivo ZIP:
Abre el proyecto
- Después de iniciar Android Studio, importa el proyecto. Elige solamente el directorio
xr-fundamentals/start
. El directorioxr-fundamentals/part1
contiene el código de la solución, que puedes consultar en cualquier momento si no logras avanzar o si deseas ver el proyecto completo.
Familiarízate con el código
- Después de abrir el proyecto en Android Studio, dedica un momento a analizar el código de partida.
3. Descubre los conceptos de realidad extendida: Modos y paneles espaciales
En este codelab, aprenderás dos conceptos de Android XR: los modos y los paneles espaciales. También aprenderás a aplicar estos conceptos a apps que se ejecuten en un dispositivo Android XR.
Modos
En dispositivos Android XR, las apps se ejecutan en uno de dos modos: el modo de espacio principal o el modo de espacio completo.
Modo de espacio principal
En el modo de espacio principal, varias apps se ejecutan una al lado de la otra para que los usuarios puedan realizar varias tareas a la vez en las apps. Las apps para Android se pueden ejecutar en el modo de espacio principal sin modificación.
Modo de espacio completo
En el modo de espacio completo, se ejecuta una app a la vez sin límites de espacio. Todas las demás apps se ocultan. Las apps deben realizar un trabajo adicional para abrir el modo de espacio completo y usar las capacidades complementarias disponibles para ellas en este modo.
Para obtener más información sobre estos modos, consulta Modos de espacio principal y de espacio completo.
Paneles espaciales
Los paneles espaciales son elementos contenedores que constituyen los componentes básicos de las apps para Android XR.
Cuando se ejecuta en el modo de espacio principal, la app estará contenida dentro de un único panel para lograr una experiencia similar al modo de ventanas de escritorio en un dispositivo Android de pantalla grande.
Cuando se ejecuta en el modo de espacio completo, se puede dividir el contenido de la app en uno o más paneles para ofrecer una experiencia más inmersiva.
Para obtener más información sobre los paneles, consulta Paneles espaciales.
4. Ejecuta la app en el emulador de Android XR
Antes de comenzar a mejorar la app para Android XR, puedes ejecutarla en el emulador de Android XR para ver qué aspecto tiene en el modo de espacio principal.
Instala la imagen del sistema de Android XR
- Primero, abre SDK Manager en Android Studio y selecciona la pestaña SDK Platforms si aún no está seleccionada. En la esquina inferior derecha de la ventana de SDK Manager, asegúrate de que esté marcada la casilla junto a Show package details.
- En la sección Android 14, instala la imagen del emulador Android XR ARM 64 v8a o Android XR Intel x86_64. Las imágenes solo se pueden ejecutar en máquinas que tienen su misma arquitectura (x86/ARM).
Crea un dispositivo virtual Android XR
- Después de abrir el Administrador de dispositivos, selecciona XR en la columna Category en la parte izquierda de la ventana. Luego, selecciona el perfil de hardware XR Device de la lista y haz clic en Next.
- En la siguiente página, selecciona la imagen del sistema que instalaste anteriormente. Haz clic en Next y selecciona las opciones avanzadas que desees antes de crear el AVD haciendo clic en Finish.
- Ejecuta la app en el AVD que acabas de crear.
5. Configura dependencias
Antes de poder comenzar a agregar funciones específicas de realidad extendida a tu app, tendrás que agregar una dependencia en Jetpack Compose para la biblioteca de realidad extendida, androidx.xr.compose:compose
, que contiene todos los elementos componibles que necesitas para compilar una experiencia optimizada de Android XR para tu app.
libs.version.toml
[versions]
...
xrCompose = "1.0.0-alpha01"
[libraries]
...
androidx-xr-compose = { group = "androidx.xr.compose", name = "compose", version.ref = "xrCompose" }
build.gradle.kts (módulo :app)
dependencies {
...
implementation(libs.androidx.xr.compose)
...
}
Después de actualizar estos archivos, asegúrate de hacer una sincronización de Gradle para que las dependencias se descarguen en tu proyecto.
6. Abre el modo de espacio completo
Para usar las funciones de realidad extendida como paneles, una app debe ejecutarse en el modo de espacio completo. Una app puede abrir el modo de espacio completo de dos formas:
- De forma programática, como en respuesta a la interacción del usuario dentro de tu app
- Inmediatamente después del inicio, agregando una directiva al manifiesto de la app
Cómo abrir el modo de espacio completo de forma programática
Para abrir el modo de espacio completo de forma programática, puedes ofrecer indicaciones visuales en tu IU para que el usuario pueda controlar en qué modo quiere usar tu app. Además, puedes abrir el modo de espacio completo cuando corresponda según el contexto de uso de la app. Por ejemplo, se puede abrir el modo de espacio completo cuando se comienza a ver contenido de video y salir de él cuando finaliza la reproducción.
Para simplificar las cosas, este proceso se puede lograr agregando un botón en la barra superior de la aplicación para activar o desactivar el modo.
- Crea un nuevo archivo
ToggleSpaceModeButton.kt
en el paquetecom.example.android.xrfundamentals.ui.component
y agrega los siguientes elementos componibles:
ToggleSpaceModeButton.kt
package com.example.android.xrfundamentals.ui.component
import androidx.annotation.DrawableRes
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.xr.compose.platform.LocalSpatialCapabilities
import androidx.xr.compose.platform.LocalSpatialConfiguration
import com.example.android.xrfundamentals.R
import com.example.android.xrfundamentals.ui.theme.XRFundamentalsTheme
@Composable
fun ToggleSpaceModeButton(modifier: Modifier = Modifier) {
val spatialConfiguration = LocalSpatialConfiguration.current
if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
ToggleSpaceModeButton(
modifier = modifier,
contentDescription = "Request Home Space mode",
iconResource = R.drawable.ic_home_space_mode,
onClick = { spatialConfiguration.requestHomeSpaceMode() }
)
} else {
ToggleSpaceModeButton(
modifier = modifier,
contentDescription = "Request Full Space mode",
iconResource = R.drawable.ic_full_space_mode,
onClick = { spatialConfiguration.requestFullSpaceMode() }
)
}
}
@Composable
fun ToggleSpaceModeButton(
contentDescription: String,
@DrawableRes iconResource: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
IconButton(
modifier = modifier,
onClick = onClick
) {
Icon(
painterResource(iconResource),
contentDescription
)
}
}
- Agrega el botón como una acción en la
TopAppBar
cuando la app se esté ejecutando en un dispositivo de realidad extendida.
XRFundamentalsTopAppBar.kt
import androidx.xr.compose.platform.LocalHasXrSpatialFeature
...
TopAppBar(
...,
actions = {
// Only show the mode toggle if the device supports spatial UI
if (LocalHasXrSpatialFeature.current) {
ToggleSpaceModeButton()
}
}
)
Ahora, ejecuta la app.
La app ejecutándose en el modo de espacio principal cuando se inicia. Presiona el botón de la parte superior derecha del panel para cambiar al modo de espacio completo. | La app ejecutándose en el modo de espacio completo. Ten en cuenta que ya no está la IU del sistema para minimizar/cerrar la app. Presiona el botón de la parte superior derecha del panel para volver al modo de espacio principal. |
Estos fragmentos incluyen algunas APIs nuevas para observar:
LocalSpatialConfiguration
es un local de composición que ofrece acceso a la configuración espacial actual de la app. Más allá de los métodos para solicitar cambiar de modo, esto incluye otra información como el tamaño del volumen que contiene la app.LocalSpatialCapabilities
es un local de composición que se puede usar para determinar qué capacidades espaciales están disponibles para que use una app. Además del modo (espacio principal o espacio completo), esto incluye capacidades como audio espacial y compatibilidad con contenido 3D.LocalHasXrSpatialFeature
es un local de composición que se puede usar para determinar si la app se está ejecutando en un dispositivo compatible con funciones de IU espaciales. Bajo la superficie, verifica si el dispositivo tiene la función del sistemaandroid.software.xr.immersive
.
Cómo abrir el modo de espacio completo al inicio
Para indicar al SO que inicie una actividad en el modo de espacio completo, puedes incluir un elemento <property>
con los siguientes atributos dentro del elemento <activity>
correspondiente. Esto se recomienda únicamente si no es probable que los usuarios quieran usar otra app al mismo tiempo en que están usando la tuya.
AndroidManifest.xml
<activity
android:name=".MainActivity"
... >
<property
android:name="android.window.PROPERTY_XR_ACTIVITY_START_MODE"
android:value="XR_ACTIVITY_START_MODE_FULL_SPACE_MANAGED" />
</activity>
Ahora, cuando se inicia la app, el usuario es llevado inmediatamente al modo de espacio completo.
Antes de continuar, quita el elemento <property>
mencionado antes del manifiesto para que la app use el comportamiento predeterminado de abrirse en el modo de espacio principal.
7. Divide la IU en varios paneles
Ahora que tu app puede abrir el modo de espacio completo y salir de él, es momento de aprovecharlo mejor. Una fantástica forma de hacerlo es dividir el contenido de tu app en varios paneles para llenar el espacio y (opcionalmente) permitir que los usuarios muevan los paneles y les cambien el tamaño como lo deseen.
Incorpora tu app a un subespacio
Para comenzar, agrega un elemento Subspace
componible después del elemento Scaffold
componible en el elemento XRFundamentalsApp
componible. Los subespacios son una partición de espacio 3D dentro de tu app, en donde puedes compilar diseños 3D (p. ej., agregando paneles espaciales), colocar modelos 3D y agregar profundidad a contenido que, de otra forma, es 2D.
Cuando se ejecuta en un dispositivo que no es de realidad extendida, el contenido del elemento Subspace
componible nunca entra en la composición. Cuando se ejecuta en un dispositivo de realidad extendida, el contenido solo entra en la composición cuando la app se está ejecutando en el modo de espacio completo.
XRFundamentalsApp.kt
import androidx.xr.compose.spatial.Subspace
...
HelloAndroidXRTheme {
Scaffold(...)
Subspace {
}
}
Ahora, ejecuta la app:
Cuando tu app incluye un elemento Subspace
componible, este se mostrará en lugar del contenido 2D. Esto significa que, cuando hagas clic en el botón para abrir el modo de espacio completo, ya no se mostrará nada. Para corregir esto, debes agregar dos paneles espaciales en los siguientes pasos: uno que contenga el contenido principal y otro que contenga el contenido secundario.
Agrega un panel para el contenido principal
Para mostrar el contenido principal en el modo de espacio completo, agrega un SpatialPanel
dentro del elemento componible Subspace
.
Debido a que este es el panel principal de la app, puedes incluir el Scaffold
dentro de él para mantener presentes los controles dentro de la barra superior de la aplicación. En el siguiente codelab, aprenderás sobre órbitas, que se pueden usar para asignar el espacio de los controles que suele contener la barra de la aplicación, como acciones de navegación y específicas del contexto.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.SpatialPanel
...
Subspace {
SpatialPanel() {
Scaffold(
topBar = { XRFundamentalsTopAppBar() }
) { innerPadding ->
Box(Modifier.padding(innerPadding)) {
PrimaryCard(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
)
}
}
}
}
Vuelve a ejecutar la app, y verás que el SpatialPanel
con el contenido principal se ve en el modo de espacio completo, pero es muy pequeño.
Modifica el panel principal
Para que el panel principal se pueda usar mejor, puedes agrandarlo con un SubspaceModifier
. Los modificadores de subespacios son similares a los modificadores y se usan para cambiar componentes espaciales como los paneles.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
import androidx.compose.ui.unit.dp
...
SpatialPanel(
modifier = SubspaceModifier
.width(1024.dp)
.height(800.dp)
){
...
}
Vuelve a ejecutar la app. El panel principal debería ocupar mucho más espacio.
Agrega un panel para el contenido secundario
Ahora que estás ejecutando la app en el modo de espacio completo y usando un panel para mostrar el contenido principal, es momento de mover el contenido secundario a su propio panel. Observa el uso de una Surface
dentro del panel espacial. Sin ella, no habría un segundo plano para las tarjetas secundarias, ya que los paneles espaciales son transparentes (el elemento Scaffold
componible controló este aspecto en el paso anterior).
XRFundamentalsApp.kt
Subspace {
SpatialPanel() { ... }
SpatialPanel(
modifier = SubspaceModifier
.width(340.dp)
.height(800.dp)
) {
Surface {
SecondaryCardList(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
)
}
}
}
Ahora, vuelve a ejecutar la app. A simple vista, puede parecer que el segundo panel no se ve, pero en realidad sí (solo que está oculto detrás del panel principal).
Diseña los paneles en una fila
Al igual que con el contenido 2D, el uso de filas y columnas es útil para organizar elementos componibles uno al lado del otro sin superponerse. Al trabajar con componentes espaciales como paneles, puedes usar los elementos SpatialRow
y SpatialColumn
componibles para lograrlo.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.SpatialRow
...
Subspace {
SpatialRow(
curveRadius = 825.dp
) {
SpatialPanel(...) { ... }
SpatialPanel(...) { ... }
}
}
Ejecuta la app una vez más. Deberías ver que los paneles están diseñados en una fila, uno detrás del otro. Además, gracias al curveRadius
proporcionado a la SpatialRow
, los paneles se curvan alrededor del usuario en lugar de permanecer en el mismo plano, lo cual ofrece una experiencia más abarcativa.
Haz que los paneles se puedan cambiar de tamaño
Para darles a los usuarios el control de la apariencia de su app, puedes ofrecer la posibilidad de cambiar el tamaño de los paneles usando el modificador de subespacios resizable
.
De forma predeterminada, los paneles de tamaño variable se pueden achicar a cero o expandir de forma indefinida. Por lo tanto, recomendamos que te tomes el tiempo para configurar los parámetros minimumSize
y maximumSize
adecuados en función del contenido que tendrán.
Consulta la documentación de referencia para obtener más detalles de todos los parámetros que admite el modificador resizable
.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.layout.resizable
...
SpatialPanel(
modifier = SubspaceModifier
...
.resizable(true)
)
Haz que los paneles se puedan mover
De forma similar, puedes hacer que los paneles se muevan usando el modificador de subespacios movable
.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.layout.movable
...
SpatialPanel(
modifier = SubspaceModifier
...
.movable(true)
)
Consulta la documentación de referencia para obtener más detalles de todos los parámetros que admite el modificador movable
.
8. Felicitaciones
Para continuar aprendiendo a aprovechar al máximo la realidad extendida, consulta los siguientes recursos y ejercicios. También puedes solicitar participar en el bootcamp de realidad extendida.
Lecturas adicionales
- Diseño para realidad extendida abarca los principios y las prácticas recomendadas de diseño para usar al compilar apps para Android XR.
- Cómo desarrollar con el SDK de realidad extendida de Jetpack incluye orientación técnica sobre las APIs y las herramientas que puedes usar al compilar tu experiencia de Android XR.
- La página de los lineamientos de calidad de las apps para Android XR describe los criterios de creación de una excelente experiencia del usuario.
- Explora la muestra de Hello Android XR.
Desafíos
- Usa los parámetros adicionales disponibles para los modificadores de subespacios
resizable
ymovable
. - Agrega paneles adicionales.
- Usa otros componentes espaciales como un diálogo espacial.