Instructivos

Cómo llevar Androidify a la realidad extendida con el SDK de Jetpack XR

Lectura de 9 min
Dereck Bridie
Ingeniera de Relaciones con Desarrolladores

Samsung Galaxy XR ya está aquí, con tecnología de Android XR. Esta entrada de blog forma parte de nuestra Semana de Android XR, en la que proporcionamos recursos (entradas de blog, videos, código de muestra y mucho más) diseñados para ayudarte a aprender, compilar y preparar tus apps para Android XR.

Con el lanzamiento de Samsung Galaxy XR , el primer dispositivo con tecnología de Android XR ya está aquí oficialmente. Ahora, las personas pueden disfrutar de muchas de sus apps favoritas de Play Store en una dimensión completamente nueva: la tercera dimensión.

La tercera dimensión es espaciosa y tiene mucho espacio para tus apps. Comienza hoy mismo con las herramientas que funcionen para tu app. Por ejemplo, puedes usar el SDK de Jetpack XR para crear experiencias de realidad extendida envolventes con herramientas modernas de desarrollo de Android, como Kotlin y Compose.

En esta entrada de blog, te contaremos nuestro propio recorrido mientras llevamos la fantasía de nuestra querida app de Androidify a la realidad extendida y abordaremos los aspectos básicos de lo que se necesita para llevar tus apps a la realidad extendida.

Un recorrido por Androidify

Androidify es una app de código abierto que te permite crear bots de Android con algunas de las tecnologías más recientes, como Gemini, CameraX, Navigation 3 y, por supuesto, Jetpack Compose. Androidify se diseñó inicialmente para verse bien en teléfonos, dispositivos plegables y tablets mediante la creación de diseños adaptables.

customize.png

Androidify se ve muy bien en varios factores de forma

Un pilar clave de los diseños adaptables son los elementos componibles reutilizables. Jetpack Compose te ayuda a crear componentes de IU pequeños que se pueden diseñar de diferentes maneras para crear experiencias de usuario intuitivas, sin importar el tipo de dispositivo que use el usuario. De hecho, Androidify es compatible con Android XR sin modificaciones en la app.

customize_2.png

Androidify se adapta a la realidad extendida con su diseño responsivo de pantalla grande sin cambios de código

Las apps que no tienen un manejo especial para Android XR pueden realizar varias tareas en una ventana de tamaño adecuado y funcionan de manera similar a lo que harían en una pantalla grande. Por este motivo, Androidify ya está completamente disponible en Android XR sin trabajo adicional. Sin embargo, no queríamos detenernos allí, por lo que decidimos ir más allá y crear una app diferenciada de realidad extendida para brindar una experiencia agradable a nuestros usuarios de realidad extendida.

Cómo orientarse en la realidad extendida

Repasemos los conceptos básicos clave para Android XR, comenzando con los dos modos en los que se pueden ejecutar las apps: Espacio principal y Espacio completo.

homespace.png
Apps en el Espacio principal
homespace2.png
App en el Espacio completo

En Espacio principal, se pueden ejecutar varias apps una al lado de la otra para que los usuarios puedan realizar varias tareas a la vez en diferentes ventanas. En ese sentido, se parece mucho al modo de ventanas de escritorio en un dispositivo Android de pantalla grande, pero en el espacio virtual.

En Espacio completo, la app no tiene límites de espacio y puede usar las funciones espaciales completas de Android XR, como la IU espacial y el control del entorno virtual.

Si bien puede parecer tentador hacer que tu app se ejecute solo en el Espacio completo, es posible que los usuarios quieran realizar varias tareas a la vez con tu app, por lo que admitir ambos modos promueve una mejor experiencia del usuario.

Cómo diseñar para la nueva dimensión de Androidify

Una app agradable comienza con un diseño excelente. Ivy Knight, defensora sénior de diseño en Android DevRel, se encargó de tomar los diseños existentes para Androidify y crear un nuevo diseño para la realidad extendida. Adelante, Ivy.

El diseño para la realidad extendida requería un enfoque único, pero, en realidad, aún tenía mucho en común con el diseño para dispositivos móviles. Comenzamos pensando en la contención: cómo organizar y agrupar nuestros elementos de la IU en el subespacio, ya sea mostrando claramente los límites o insinuándolos de forma sutil. También aprendimos a adoptar todos los tamaños diferentes de los elementos de la IU espacial, que están diseñados para ajustarse y moverse en respuesta al usuario. Al igual que con Androidify, compila con diseños adaptables, para que puedas dividir tus diseños en partes para tu IU espacial.

Cómo comenzar el diseño con el Espacio principal

Por suerte, Android XR te permite comenzar con tu app tal como está hoy para el Espacio principal, por lo que pudimos hacer la transición a los diseños expandidos de realidad extendida con solo agregar una barra de herramientas de ventana y un botón de transición de Espacio completo.

También consideramos las posibles funciones de hardware y cómo interactuaría el usuario con ellas. Los diseños para dispositivos móviles de Androidify se adaptan a varias posturas, tamaños de clase y la cantidad de cámaras para ofrecer más opciones de fotos. Siguiendo este modelo, también tuvimos que adaptar el diseño de la cámara para los dispositivos de auriculares. También debimos realizar ajustes para que el texto funcione y tenga en cuenta la proximidad de la IU al usuario.

Cómo diseñar para el cambio más grande al Espacio completo

El Espacio completo fue el cambio más grande, pero nos dio el espacio más creativo para adaptar nuestro diseño. 

tablet_to_xr.webp
De la tablet a la realidad extendida

Androidify usa contención visual o paneles para agrupar funciones con un fondo y un contorno, como el panel "Tomar o elegir una foto". También usamos componentes como la barra superior de la app para crear una contención natural enmarcando los otros paneles. Por último, la contención intrínseca se sugiere por la proximidad de ciertos elementos a otros, como el botón inferior "Iniciar transformación", que está cerca del panel "Elegir el color de mi bot".

Los paneles espaciales facilitaron la separación. Para decidir cómo adaptar tus diseños para dispositivos móviles a los paneles espaciales, intenta quitar las superficies comenzando por la que está más atrás y, luego, avanzando. Consulta cuántos fondos puedes quitar y qué queda. Después de hacer este ejercicio para Androidify, lo que quedó fue el garabato verde grande de Android. El garabato no solo actuó como un momento de marca y fondo, sino también como un ancla para el contenido en el espacio 3D.

Establecer este ancla facilitó la imaginación de cómo los elementos podían moverse a su alrededor y cómo podíamos usar la proximidad para salir y traducir el resto de la experiencia del usuario.

Otras sugerencias de diseño para ayudar a que tu app sea espacial

  • Permite que las cosas no estén contenidas: Quita los componentes y dales un espacio real (espacial). Es hora de darles a esos elementos de la IU un espacio para respirar.
  • Quita superficies: Oculta el fondo y observa qué sucede con tus diseños.
  • Motiva con el movimiento: ¿Cómo usas las transiciones en tu app? Usa ese personaje para imaginar que tu app se lanza a la RV.
  • Elige un ancla: No pierdas a tus usuarios en el espacio. Ten un elemento que ayude a recopilar o fundamentar la IU.

Para obtener más información sobre los patrones de diseño de la IU de realidad extendida, consulta Diseño para Android XR en Android Developers.

Conceptos básicos de la IU espacial

Ahora que analizamos la experiencia de Ivy para adaptar su mentalidad mientras diseñaba Androidify para la realidad extendida, hablemos sobre el desarrollo de la IU espacial. Desarrollar una IU espacial con el SDK de Jetpack XR debería parecer familiar si estás acostumbrado a trabajar con herramientas y bibliotecas modernas de Android. Encontrarás conceptos con los que ya estás familiarizado, como la creación de diseños con Compose. De hecho, los diseños espaciales son muy similares a los diseños 2D que usan filas, columnas y espaciadores:

spatialrows.png

Estos elementos están dispuestos en SpatialRowsSpatialColumns

Los elementos espaciales que se muestran aquí son elementos componibles SpatialPanel, que te permiten mostrar contenido 2D, como texto, botones y videos.

Subspace {
    SpatialPanel(
        SubspaceModifier
            .height(824.dp)
            .width(1400.dp)
    ) {
        Text("I'm a panel!")
    }
}

Un SpatialPanel es un elemento componible de subespacio. Los elementos componibles de subespacio deben estar contenidos dentro de un subespacio y se modifican con objetos SubspaceModifier. Los subespacios se pueden colocar en cualquier lugar dentro de la jerarquía de la IU de tu app y solo pueden contener elementos componibles de subespacio.Los objetos SubspaceModifier también son muy similares a los objetos Modifier: controlan parámetros como el tamaño y el posicionamiento.

Se puede adjuntar un Orbiter a un SpatialPanel y moverlo junto con el contenido al que está adjunto. A menudo, se usan para proporcionar controles contextuales sobre el contenido al que están adjuntos, lo que le da al contenido el enfoque principal. Se pueden colocar en cualquiera de los cuatro lados del contenido, a una distancia configurable.

orbiter.png
Un Orbiter está adjunto a la parte inferior de un SpatialPanel

Hay muchos más elementos de la IU espacial, pero estos son los principales que usamos para crear diseños espaciales para Androidify.

Cómo comenzar con el desarrollo de realidad extendida

Comencemos con la configuración del proyecto. Agregamos la dependencia de Jetpack XR Compose, que puedes encontrar en la página de dependencias de Jetpack XR.

Agregamos código para un botón que hace la transición del usuario al Espacio completo, comenzando por detectar la capacidad para hacerlo:

@Composable
fun couldRequestFullSpace(): Boolean =
   LocalSpatialConfiguration.current.hasXrSpatialFeature && 
   !LocalSpatialCapabilities.current.isSpatialUiEnabled
}

Luego, creamos un nuevo componente de botón que usa el ícono Expandir contenido en nuestros diseños existentes y le dimos un comportamiento onClick:

@Composable

fun RequestFullSpaceIconButton() {
   if (!couldRequestFullSpace()) return
   val session = LocalSession.current ?: return

   IconButton(
       onClick = {
           session.scene.requestFullSpaceMode()
       },
   ) {
       Icon(
           imageVector =  
               vectorResource(R.drawable.expand_content_24px),
           contentDescription = 
               stringResource("To Full Space"),
       )
   }
}

Ahora, cuando se hace clic en ese botón, solo se muestra el diseño mediano en el Espacio completo. Podemos verificar las capacidades espaciales y determinar si se puede mostrar la IU espacial. En ese caso, mostraremos nuestro nuevo diseño espacial:

@Composable

fun HomeScreenContents(layoutType: HomeScreenLayoutType) {
   val layoutType = when {
      LocalSpatialCapabilities.current.isSpatialUiEnabled -> 
          HomeScreenLayoutType.Spatial
      isAtLeastMedium() -> HomeScreenLayoutType.Medium
      else -> HomeScreenLayoutType.Compact
   }

   when (layoutType) {
      HomeScreenLayoutType.Compact ->
          HomeScreenCompactPager(...)

      HomeScreenLayoutType.Medium ->
          HomeScreenMediumContents(...)

      HomeScreenLayoutType.Spatial ->
          HomeScreenContentsSpatial(...)
   }
}

Cómo implementar el diseño de la pantalla principal

Volvamos al diseño espacial de la pantalla principal en el Espacio completo para comprender cómo se implementó.

customize_3.png

Identificamos dos elementos SpatialPanel aquí: un panel en el que se encuentra la tarjeta de video a la derecha y uno que contiene la IU principal. Por último, hay un Orbiter adjunto en la parte superior. Comencemos con el panel del reproductor de video:

@Composable
fun HomeScreenContentsSpatial(...) {
   Subspace {
      SpatialPanel(SubspaceModifier
                   .fillMaxWidth(0.2f)
                   .fillMaxHeight(0.8f)
                   .aspectRatio(0.77f)
                   .rotate(0f, 0f, 5f),
      ) {
          VideoPlayer(videoLink)
      }
   }
}

Simplemente volvimos a usar el componente VideoPlayer 2D de los diseños normales en un SpatialPanel sin cambios adicionales. Así se ve de forma independiente:

bluetiel.png

El panel de contenido principal siguió la misma historia: volvimos a usar el contenido del panel mediano en un SpatialPanel.

SpatialPanel(SubspaceModifier.fillMaxSize(),
             resizePolicy = ResizePolicy(
                 shouldMaintainAspectRatio = true
             ),
             dragPolicy = MovePolicy()
) {
    Box {
        FillBackground(R.drawable.squiggle_full)
        HomeScreenSpatialMainContent(...)
    }
}

Le dimos a este panel una ResizePolicy, que le da al panel algunos controladores cerca de los bordes que permiten al usuario cambiar el tamaño del panel. También tiene una MovePolicy, que permite al usuario arrastrarlo.

customize_4.png

Colocarlos en el mismo subespacio los hace independientes entre sí, por lo que hicimos que el panel VideoPlayer sea un elemento secundario del panel de contenido principal. Esto hace que el panel VideoPlayer se mueva cuando se arrastra el panel de contenido principal a través de una relación entre superior y secundario.

@Composable
fun HomeScreenContentsSpatial(...) {
   Subspace {
       SpatialPanel(SubspaceModifier..., resizePolicy, dragPolicy) {
           Box {
               FillBackground(R.drawable.squiggle_full)
               HomeScreenSpatialMainContent(...)
           }
           Subspace {
              SpatialPanel(SubspaceModifier...) {
                  VideoPlayer(videoLink)
              }
           }
       }
   }
}

Así hicimos la primera pantalla.

Cómo pasar a las otras pantallas

También repasaré brevemente algunas de las otras pantallas y destacaré las consideraciones específicas que se hicieron para cada una.

fullspace.png
La pantalla de creación en el Espacio completo

Aquí, usamos elementos componibles SpatialRow y SpatialColumn para crear un diseño que se ajuste al espacio de visualización recomendado y, nuevamente, reutilizamos componentes del diseño mediano.

fullspace_2.png

Pantalla de resultados en el Espacio completo: Un bot generado con una instrucción: gorra de béisbol roja, lentes de sol de aviador, camiseta azul claro, shorts a cuadros rojos y blancos, chanclas verdes y una raqueta de tenis.


La pantalla de resultados muestra las citas complementarias con un efecto de difuminado, lo que permite que se desvanezcan cerca de los bordes de la pantalla. También usa una transición 3D real cuando se ve la entrada que se usó, lo que hace que la imagen se voltee en el espacio.

Cómo publicar en Google Play Store

Ahora que la app está lista para la realidad extendida con los diseños espaciales, la lanzamos en Play Store. Hay un último cambio importante que hicimos en el archivo AndroidManifest.xml de la app:

<!-- Androidify can use XR features if they're available; they're not required. -->
<uses-feature android:name="android.software.xr.api.spatial" 
              android:required="false" />

Esto permite que Play Store sepa que esta app tiene funciones diferenciadas de realidad extendida, lo que muestra una insignia que les informa a los usuarios que la app se creó teniendo en cuenta la realidad extendida:

androidify2.png
Androidify como se muestra en Google Play Store en Android XR


Cuando subimos la versión, no necesitamos ningún paso especial para lanzar la realidad extendida: la misma app se distribuye de forma normal a los usuarios en el segmento para dispositivos móviles que a los usuarios en un dispositivo de realidad extendida. Sin embargo, puedes agregar capturas de pantalla específicas de realidad extendida de tu app o incluso subir una vista previa envolvente de tu app con un recurso de video espacial. En dispositivos Android XR, Play Store muestra automáticamente esto como una vista previa 3D envolvente, lo que permite a los usuarios experimentar la profundidad y la escala de tu contenido antes de instalar la app.

Comienza a crear tus propias experiencias hoy mismo

Androidify es un excelente ejemplo de cómo espacializar una app existente de Jetpack Compose 2D. Hoy, mostramos el proceso completo de desarrollo de una IU espacial para Androidify, desde el diseño hasta el código y la publicación. Modificamos los diseños existentes para que funcionen con paradigmas espaciales, usamos elementos componibles SpatialPanel y Orbiter para crear diseños espaciales que se muestran cuando el usuario ingresa al Espacio completo y, por último, lanzamos la nueva versión de la app en Play Store.

Esperamos que esta entrada de blog te haya ayudado a comprender cómo puedes llevar tus propias apps a Android XR. Aquí hay algunos vínculos más que pueden ayudarte en tu camino:

Escrito por:

Seguir leyendo