Mit Jetpack Compose for XR können Sie Ihre räumliche Benutzeroberfläche und Ihr Layout deklarativ mithilfe bekannter Compose-Konzepte wie Zeilen und Spalten erstellen. So können Sie Ihre vorhandene Android-Benutzeroberfläche in den 3D-Raum erweitern oder völlig neue immersive 3D-Anwendungen erstellen.
Wenn Sie eine vorhandene Android Views-basierte App orten möchten, haben Sie mehrere Entwicklungsoptionen. Sie können Interoperabilitäts-APIs verwenden, Compose und Ansichten zusammen verwenden oder direkt mit der SceneCore-Bibliothek arbeiten. Weitere Informationen finden Sie in unserem Leitfaden zur Arbeit mit Ansichten.
Unterräume und lokalisierte Komponenten
Wenn Sie eine App für Android XR entwickeln, ist es wichtig, die Konzepte Unterraum und räumliche Komponenten zu verstehen.
Subspace
Wenn Sie für Android XR entwickeln, müssen Sie Ihrer App oder Ihrem Layout einen Unterraum hinzufügen. Ein Unterraum ist eine Partition des 3D-Raums in Ihrer App, in der Sie 3D-Inhalte platzieren, 3D-Layouts erstellen und ansonsten 2D-Inhalten Tiefe verleihen können. Ein Unterraum wird nur gerendert, wenn die Spatialisierung aktiviert ist. Im Home Space oder auf Nicht-XR-Geräten wird jeglicher Code in diesem Unterraum ignoriert.
Es gibt zwei Möglichkeiten, einen Unterraum zu erstellen:
setSubspaceContent
: Mit dieser Funktion wird ein Unterraum auf App-Ebene erstellt. Diese Funktion kann in Ihrer MainActivity auf die gleiche Weise aufgerufen werden wiesetContent
. Ein Unterraum auf App-Ebene ist unbegrenzt in Höhe, Breite und Tiefe und bietet im Grunde ein unbegrenztes Canvas für räumliche Inhalte.Subspace
: Dieses Composeable kann überall in der UI-Hierarchie Ihrer App platziert werden. So können Sie Layouts für 2D- und räumliche UIs beibehalten, ohne den Kontext zwischen den Dateien zu verlieren. So können Sie z. B. die vorhandene App-Architektur zwischen XR und anderen Formfaktoren teilen, ohne den Status durch den gesamten UI-Baum hochladen oder Ihre App neu entwerfen zu müssen.
Weitere Informationen finden Sie unter Ihrer App einen untergeordneten Bereich hinzufügen.
Informationen zu lokalisierten Komponenten
Subspace-Kompositionen: Diese Komponenten können nur in einem Unterbereich gerendert werden.
Sie müssen in Subspace
oder setSubspaceContent
eingeschlossen sein, bevor sie in ein 2D-Layout eingefügt werden können. Mit einem SubspaceModifier
können Sie Ihren Subspace-Kompositionen Attribute wie Tiefe, Offset und Position hinzufügen.
- Hinweis zu Unterraummodifikatoren: Achten Sie genau auf die Reihenfolge der
SubspaceModifier
APIs.- Der Offset muss zuerst in einer Modifikatorkette auftreten.
- „Beweglich“ und „Größenanpassbar“ müssen als letztes angegeben werden.
- Drehen muss vor dem Skalieren angewendet werden
Andere lokalisierte Komponenten müssen nicht innerhalb eines Unterraums aufgerufen werden. Sie bestehen aus herkömmlichen 2D-Elementen, die in einem räumlichen Container verpackt sind. Diese Elemente können in 2D- oder 3D-Layouts verwendet werden, wenn sie für beide definiert sind. Wenn die räumliche Darstellung nicht aktiviert ist, werden die räumlichen Elemente ignoriert und es wird auf die 2D-Entsprechungen zurückgegriffen.
Einen Bereich für die Raumaufzeichnung erstellen
Ein SpatialPanel
ist ein zusammensetzbarer Unterraum, in dem Sie App-Inhalte anzeigen können. So können Sie beispielsweise Videowiedergabe, Standbilder oder andere Inhalte in einem Raumbereich anzeigen.
Mit SubspaceModifier
können Sie die Größe, das Verhalten und die Position des Bereichs „Statistiken für die Standortermittlung“ ändern, wie im folgenden Beispiel gezeigt.
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
)
}
}
Wichtige Punkte zum Code
- Hinweis zu Unterraummodifikatoren: Achten Sie genau auf die Reihenfolge der
SubspaceModifier
APIs.- Der Offset muss zuerst in einer Modifikatorkette auftreten.
- Verschiebbare und skalierbare Modifikatoren müssen als letztes angegeben werden.
- Die Drehung muss vor dem Skalieren angewendet werden.
- Da
SpatialPanel
APIs Subspace-Kompositionen sind, müssen Sie sie inSubspace
odersetSubspaceContent
aufrufen. Wenn Sie sie außerhalb eines Unterraums aufrufen, wird eine Ausnahme ausgelöst. - Ermöglichen Sie es Nutzern, die Größe des Steuerfelds zu ändern oder es zu verschieben, indem Sie
.movable
oder.resizable
SubspaceModifier
hinzufügen. - Weitere Informationen zu Größe und Positionierung finden Sie in unserer Anleitung zum Design von Infofeldern. Weitere Informationen zur Codeimplementierung finden Sie in unserer Referenzdokumentation.
Orbiter erstellen
Ein Orbiter ist eine räumliche UI-Komponente. Es ist für die Anbringung an einem entsprechenden Infofeld für Orte vorgesehen und enthält Navigations- und Kontextaktionselemente, die sich auf dieses Infofeld beziehen. Wenn Sie beispielsweise ein räumliches Steuerfeld zum Anzeigen von Videoinhalten erstellt haben, können Sie die Steuerelemente für die Videowiedergabe in einem Orbiter hinzufügen.
Rufen Sie wie im folgenden Beispiel einen Orbiter in einem SpatialPanel
auf, um Steuerelemente wie die Navigation einzubinden. Dabei werden sie aus Ihrem 2D-Layout extrahiert und gemäß Ihrer Konfiguration an das Infofeld für die Raumaufteilung angehängt.
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
)
}
}
}
}
Wichtige Punkte zum Code
- Hinweis zu Subspace-Modifizierern: Achten Sie genau auf die Reihenfolge der
SubspaceModifier
APIs.- Der Offset muss zuerst in einer Modifikatorkette auftreten.
- „Beweglich“ und „Größenanpassbar“ müssen als letztes angegeben werden.
- Drehen muss vor dem Skalieren angewendet werden
- Da Orbiter räumliche UI-Komponenten sind, kann der Code in 2D- oder 3D-Layouts wiederverwendet werden. Bei einem 2D-Layout werden in Ihrer App nur die Inhalte innerhalb des Orbiters gerendert und der Orbiter selbst wird ignoriert.
- Weitere Informationen zur Verwendung und Gestaltung von Orbitern finden Sie in unseren Designrichtlinien.
Einem geografischen Layout mehrere Kartenbereiche hinzufügen
Mit SpatialRow
, SpatialColumn
, SpatialBox
und SpatialLayoutSpacer
können Sie mehrere Kartenkacheln erstellen und in SpatialLayout
platzieren.
Im folgenden Codebeispiel wird gezeigt, wie Sie dies umsetzen.
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
)
}
}
Wichtige Punkte zum Code
SpatialRow
,SpatialColumn
,SpatialBox
undSpatialLayoutSpacer
sind alle Unterraum-Kompositen und müssen in einem Unterraum platziert werden.- Mit
SubspaceModifier
können Sie das Layout anpassen. - Für Layouts mit mehreren Bereichen in einer Zeile empfehlen wir, mithilfe eines
SubspaceModifier
einen Kurvenradius von 825 dp festzulegen, damit die Bereiche den Nutzer umgeben. Weitere Informationen finden Sie in unseren Designrichtlinien.
Mit einem Volume ein 3D‑Objekt in Ihr Layout einfügen
Wenn Sie ein 3D‑Objekt in Ihr Layout einfügen möchten, müssen Sie ein zusammengesetztes Unterraumelement namens Volumen verwenden. Hier ist ein Beispiel dafür:
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
}
}
}
}
}
Wichtige Punkte zum Code
- Hinweis zu Subspace-Modifizierern: Achten Sie genau auf die Reihenfolge der
SubspaceModifier
APIs.- Der Offset muss zuerst in einer Modifikatorkette auftreten.
- „Beweglich“ und „Größenanpassbar“ müssen als letztes angegeben werden.
- Drehen muss vor dem Skalieren angewendet werden
- Weitere Informationen zum Laden von 3D-Inhalten in einem Volume finden Sie unter 3D-Inhalte hinzufügen.
Andere UI-Komponenten für die Darstellung von Räumen hinzufügen
Räumliche UI-Komponenten können überall in der UI-Hierarchie Ihrer Anwendung platziert werden. Diese Elemente können in Ihrer 2D-Benutzeroberfläche wiederverwendet werden. Ihre räumlichen Attribute sind nur sichtbar, wenn die räumlichen Funktionen aktiviert sind. So können Sie Menüs, Dialogfelder und andere Komponenten hervorheben, ohne den Code zweimal schreiben zu müssen. Anhand der folgenden Beispiele für die räumliche Benutzeroberfläche können Sie besser nachvollziehen, wie Sie diese Elemente verwenden.
UI-Komponente |
Wenn die Spatialisierung aktiviert ist |
In einer 2D-Umgebung |
---|---|---|
|
Der Bereich wird in der Z‑Tiefe leicht nach hinten verschoben, um ein erhöhtes Dialogfeld anzuzeigen. |
Kehrt zur 2D-Ansicht |
|
Der Bereich wird in der Z‑Tiefe leicht nach hinten verschoben, um ein erhöhtes Pop-up anzuzeigen. |
Es wird zu einer 2D- |
|
Mit |
Darstellungen ohne räumliche Erhebungen. |
SpatialDialog
Das ist ein Beispiel für ein Dialogfeld, das nach einer kurzen Verzögerung geöffnet wird. Wenn SpatialDialog
verwendet wird, wird das Dialogfeld in derselben Z‑Tiefe wie das räumliche Steuerfeld angezeigt. Wenn die Spatialisierung aktiviert ist, wird das Steuerfeld um 125 dp nach hinten verschoben.
SpatialDialog
kann auch verwendet werden, wenn die Spatialisierung nicht aktiviert ist. In diesem Fall wird das 2D-Äquivalent Dialog
verwendet.
@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")
}
}
}
}
}
Wichtige Punkte zum Code
- Dies ist ein Beispiel für
SpatialDialog
. Die Verwendung vonSpatialPopUp
undSpatialElevation
ist sehr ähnlich. Weitere Informationen finden Sie in der API-Referenz.
Benutzerdefinierte Bereiche und Layouts erstellen
Wenn Sie benutzerdefinierte Steuerfelder erstellen möchten, die von Compose for XR nicht unterstützt werden, können Sie mithilfe der SceneCore
APIs direkt mit PanelEntities
und der Szenengraphik arbeiten.