Con Jetpack Compose per XR, puoi creare in modo dichiarativo l'interfaccia utente e il layout spaziali utilizzando concetti di Compose già noti, come righe e colonne. In questo modo puoi estendere l'interfaccia utente Android esistente allo spazio 3D o creare applicazioni 3D immersive completamente nuove.
Se stai spazializzando un'app basata su Android Views esistente, hai a disposizione diverse opzioni di sviluppo. Puoi utilizzare le API di interoperabilità, Compose e le visualizzazioni insieme o lavorare direttamente con la libreria SceneCore. Per ulteriori dettagli, consulta la nostra guida all'utilizzo delle visualizzazioni.
Informazioni su sottospazi e componenti spazializzati
Quando scrivi la tua app per Android XR, è importante comprendere i concetti di spazio sottostante e componenti spazializzati.
Informazioni sullo spazio sottostante
Quando sviluppi per Android XR, devi aggiungere un sottospazio all'app o al layout. Un sottospazio è una partizione dello spazio 3D all'interno dell'app in cui puoi collocare contenuti 3D, creare layout 3D e aggiungere profondità a contenuti altrimenti 2D. Un subspazio viene visualizzato solo quando la spazializzazione è attivata. In Home Space o su dispositivi non XR, qualsiasi codice all'interno di questo sottospazio viene ignorato.
Esistono due modi per creare un sottospazio:
setSubspaceContent
: questa funzione crea uno spazio sotto di livello app. Questo metodo può essere chiamato in MainActivity nello stesso modo in cui utilizzisetContent
. Uno spazio sottodimensionato a livello di app è illimitato in altezza, larghezza e profondità, fornendo essenzialmente una tela infinita per i contenuti spaziali.Subspace
: questo composable può essere posizionato in qualsiasi punto della gerarchia dell'interfaccia utente dell'app, consentendo di mantenere i layout per l'interfaccia utente 2D e spaziale senza perdere il contesto tra i file. In questo modo è più facile condividere elementi come l'architettura dell'app esistente tra XR e altri fattori di forma senza dover eseguire l'elevazione dello stato nell'intera struttura dell'interfaccia utente o ristrutturare l'app.
Per ulteriori informazioni, consulta la sezione sull'aggiunta di uno spazio secondario all'app.
Informazioni sui componenti spazializzati
Composabili in sottospazio: questi componenti possono essere visualizzati solo in un sottospazio.
Devono essere racchiusi tra Subspace
o setSubspaceContent
prima di essere collocati in un layout 2D. Un SubspaceModifier
ti consente di aggiungere attributi come profondità, offset e posizionamento ai composabili sottospazio.
- Nota sui modificatori di sottospazio: presta molta attenzione all'ordine delle API
SubspaceModifier
.- L'offset deve essere il primo elemento di una catena di modificatori
- Spostabile e ridimensionabile deve essere l'ultima opzione
- La rotazione deve essere applicata prima della scala
Gli altri componenti spazializzati non richiedono di essere chiamati all'interno di un sottospazio. Sono costituiti da elementi 2D convenzionali racchiusi in un contenitore spaziale. Questi elementi possono essere utilizzati in layout 2D o 3D se definiti per entrambi. Se la spazializzazione non è attivata, le relative funzionalità spazializzate verranno ignorate e verrà eseguito il fallback alle relative controparti 2D.
Creare un riquadro spaziale
Un SpatialPanel
è un componente componibile sottospaziale che ti consente di visualizzare i contenuti dell'app. Ad esempio, puoi visualizzare la riproduzione di video, immagini fisse o qualsiasi altro contenuto in un riquadro spaziale.
Puoi utilizzare SubspaceModifier
per modificare le dimensioni, il comportamento e il posizionamento del riquadro spaziale, come mostrato nell'esempio seguente.
Subspace {
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
.movable()
.resizable()
) {
SpatialPanelContent()
}
}
// 2D content placed within the spatial panel
@Composable
fun SpatialPanelContent(){
Box(
Modifier
.background(color = Color.Black)
.height(500.dp)
.width(500.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "Spatial Panel",
color = Color.White,
fontSize = 25.sp
)
}
}
Punti chiave del codice
- Nota sui modificatori dello spazio sottostante: presta molta attenzione all'ordine delle API
SubspaceModifier
.- L'offset deve essere il primo elemento di una catena di modificatori.
- I modificatori spostabili e ridimensionabili devono essere gli ultimi.
- La rotazione deve essere applicata prima della scala.
- Poiché le API
SpatialPanel
sono composibili in sottospazio, devi chiamarle all'interno diSubspace
osetSubspaceContent
. Se li chiami al di fuori di un sottospazio, verrà generata un'eccezione. - Consenti all'utente di ridimensionare o spostare il riquadro aggiungendo
.movable
o.resizable
SubspaceModifier
. - Per informazioni dettagliate su dimensioni e posizionamento, consulta le nostre linee guida per la progettazione dei riquadri spaziali. Per ulteriori dettagli sull'implementazione del codice, consulta la nostra documentazione di riferimento.
Creare un orbiter
Un orbiter è un componente dell'interfaccia utente spaziale. È progettato per essere associato a un riquadro spaziale corrispondente e contiene elementi di navigazione e azioni contestuali correlati a quel riquadro spaziale. Ad esempio, se hai creato un riquadro spaziale per visualizzare contenuti video, puoi aggiungere i controlli di riproduzione video all'interno di un orbiter.
Come mostrato nell'esempio seguente, chiama un orbiter all'interno di un SpatialPanel
per eseguire il wrapping dei controlli utente come la navigazione. In questo modo, vengono estratti dal layout 2D e collegati al riquadro spaziale in base alla configurazione.
setContent {
Subspace {
SpatialPanel(
SubspaceModifier
.height(824.dp)
.width(1400.dp)
.movable()
.resizable()
) {
SpatialPanelContent()
OrbiterExample()
}
}
}
//2D content inside Orbiter
@Composable
fun OrbiterExample() {
Orbiter(
position = OrbiterEdge.Bottom,
offset = 96.dp,
alignment = Alignment.CenterHorizontally
) {
Surface(Modifier.clip(CircleShape)) {
Row(
Modifier
.background(color = Color.Black)
.height(100.dp)
.width(600.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "Orbiter",
color = Color.White,
fontSize = 50.sp
)
}
}
}
}
Punti chiave del codice
- Nota sui modificatori di sottospazio: presta molta attenzione all'ordine delle API
SubspaceModifier
.- L'offset deve essere il primo elemento di una catena di modificatori
- Spostabile e ridimensionabile deve essere l'ultima opzione
- La rotazione deve essere applicata prima della scala
- Poiché gli orbiter sono componenti dell'interfaccia utente spaziale, il codice può essere riutilizzato nei layout 2D o 3D. In un layout 2D, l'app esegue il rendering solo dei contenuti all'interno dell'orbiter e ignora l'orbiter stesso.
- Consulta le nostre linee guida per la progettazione per saperne di più su come utilizzare e progettare gli orbiter.
Aggiungere più riquadri spaziali a un layout spaziale
Puoi creare più riquadri spaziali e posizionarli all'interno di un
SpatialLayout
utilizzando SpatialRow
,
SpatialColumn
, SpatialBox
e
SpatialLayoutSpacer
.
Il seguente esempio di codice mostra come eseguire questa operazione.
Subspace {
SpatialRow {
SpatialColumn {
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Top Left")
}
SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
SpatialPanelContent("Middle Left")
}
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Bottom Left")
}
}
SpatialColumn {
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Top Right")
}
SpatialPanel(SubspaceModifier.height(200.dp).width(400.dp)) {
SpatialPanelContent("Middle Right")
}
SpatialPanel(SubspaceModifier.height(250.dp).width(400.dp)) {
SpatialPanelContent("Bottom Right")
}
}
}
}
@Composable
fun SpatialPanelContent(text: String) {
Column(
Modifier
.background(color = Color.Black)
.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
Text(
text = "Panel",
color = Color.White,
fontSize = 15.sp
)
Text(
text = text,
color = Color.White,
fontSize = 25.sp,
fontWeight = FontWeight.Bold
)
}
}
Punti chiave del codice
SpatialRow
,SpatialColumn
,SpatialBox
eSpatialLayoutSpacer
sono tutti composabili in sottospazio e devono essere inseriti in un sottospazio.- Utilizza
SubspaceModifier
per personalizzare il layout. - Per i layout con più riquadri in una riga, consigliamo di impostare un raggio di curva di 825 dp utilizzando un
SubspaceModifier
in modo che i riquadri circondino l'utente. Per maggiori dettagli, consulta le nostre linee guida per la progettazione.
Utilizzare un volume per posizionare un oggetto 3D nel layout
Per posizionare un oggetto 3D nel layout, devi utilizzare un componibile sottospazio chiamato volume. Ecco un esempio di come fare.
Subspace {
SpatialPanel(
SubspaceModifier.height(1500.dp).width(1500.dp)
.resizable().movable()
) {
ObjectInAVolume(true)
Box(
Modifier.fillMaxSize(),
contentAlignment = Alignment.Center
) {
Text(
text = "Welcome",
fontSize = 50.sp,
)
}
}
}
}
@Composable
fun ObjectInAVolume(show3DObject: Boolean) {
val xrCoreSession = checkNotNull(LocalSession.current)
val scope = rememberCoroutineScope()
if (show3DObject) {
Subspace {
Volume(
modifier = SubspaceModifier
.offset(volumeXOffset, volumeYOffset, volumeZOffset) //
Relative position
.scale(1.2f) // Scale to 120% of the size
) { parent ->
scope.launch {
// Load your 3D Object here
}
}
}
}
}
Punti chiave del codice
- Nota sui modificatori di sottospazio: presta molta attenzione all'ordine delle API
SubspaceModifier
.- L'offset deve essere il primo elemento di una catena di modificatori
- Spostabile e ridimensionabile deve essere l'ultima opzione
- La rotazione deve essere applicata prima della scala
- Consulta Aggiunta di contenuti 3D per comprendere meglio come caricare contenuti 3D all'interno di un volume.
Aggiungere altri componenti dell'interfaccia utente spaziale
I componenti dell'interfaccia utente spaziale possono essere posizionati in qualsiasi punto della gerarchia dell'interfaccia utente dell'applicazione. Questi elementi possono essere riutilizzati nell'interfaccia utente 2D e i relativi attributi spaziali saranno visibili solo quando le funzionalità spaziali sono attivate. In questo modo puoi aggiungere un'elevazione a menu, finestre di dialogo e altri componenti senza dover scrivere il codice due volte. Consulta i seguenti esempi di UI spaziale per comprendere meglio come utilizzare questi elementi.
Componente UI |
Quando la spazializzazione è attivata |
In ambiente 2D |
---|---|---|
|
Il riquadro si spingerà leggermente indietro in profondità Z per visualizzare una finestra di dialogo in primo piano |
Torna alla modalità 2D |
|
Il riquadro si spingerà leggermente indietro in profondità z per visualizzare un popup in rilievo |
Torna a un |
|
|
Programmi senza elevazione spaziale. |
SpatialDialog
Questo è un esempio di finestra di dialogo che si apre dopo un breve ritardo. Quando viene utilizzato SpatialDialog
, la finestra di dialogo viene visualizzata alla stessa profondità z del riquadro spaziale e il riquadro viene spostato indietro di 125 dp quando la spazializzazione è attivata.
SpatialDialog
può essere utilizzato anche quando la spazializzazione non è attivata e si basa sulla controparte 2D: Dialog
.
@Composable
fun DelayedDialog() {
var showDialog by remember { mutableStateOf(false) }
LaunchedEffect(Unit) {
Handler(Looper.getMainLooper()).postDelayed({
showDialog = true
}, 3000)
}
if (showDialog) {
SpatialDialog (
onDismissRequest = { showDialog = false },
SpatialDialogProperties(
dismissOnBackPress = true)
){
Box(Modifier
.height(150.dp)
.width(150.dp)
) {
Button(onClick = { showDialog = false }) {
Text("OK")
}
}
}
}
}
Punti chiave del codice
- Questo è un esempio di
SpatialDialog
. L'utilizzo diSpatialPopUp
eSpatialElevation
sarà molto simile. Per ulteriori dettagli, consulta il nostro riferimento all'API.
Creare pannelli e layout personalizzati
Per creare riquadri personalizzati non supportati da Compose for XR, puoi lavorare direttamente con PanelEntities
e la scena utilizzando le API SceneCore
.
Vedi anche
- Aggiungere modelli 3D
- Sviluppare l'interfaccia utente per XR con le visualizzazioni
- Material Design per XR