Dengan Jetpack Compose untuk XR, Anda dapat mem-build UI dan tata letak spasial secara deklaratif menggunakan konsep Compose yang sudah dikenal seperti baris dan kolom. Hal ini memungkinkan Anda memperluas UI Android yang ada ke ruang 3D atau membuat aplikasi 3D imersif yang benar-benar baru.
Jika Anda melakukan spatialisasi pada aplikasi berbasis View Android yang ada, Anda memiliki beberapa opsi pengembangan. Anda dapat menggunakan API interoperabilitas, menggunakan Compose dan View secara bersamaan, atau bekerja langsung dengan library SceneCore. Lihat panduan untuk menggunakan tampilan kami untuk mengetahui detail selengkapnya.
Tentang subspace dan komponen spasial
Saat menulis aplikasi untuk Android XR, penting untuk memahami konsep subruang dan komponen spasial.
Tentang subspace
Saat mengembangkan untuk Android XR, Anda harus menambahkan subspace ke aplikasi atau tata letak. Subruang adalah partisi ruang 3D dalam aplikasi tempat Anda dapat menempatkan konten 3D, membuat tata letak 3D, dan menambahkan kedalaman ke konten 2D. Subruang hanya dirender jika spatialisasi diaktifkan. Di Ruang Rumah atau di perangkat non-XR, kode apa pun dalam subruang tersebut akan diabaikan.
Ada dua cara untuk membuat subruang:
setSubspaceContent
: Fungsi ini membuat subruang tingkat aplikasi. Ini dapat dipanggil di MainActivity dengan cara yang sama seperti Anda menggunakansetContent
. Subruang tingkat aplikasi tidak terbatas dalam tinggi, lebar, dan kedalaman, yang pada dasarnya menyediakan kanvas tanpa batas untuk konten spasial.Subspace
: Composable ini dapat ditempatkan di mana saja dalam hierarki UI aplikasi, sehingga Anda dapat mempertahankan tata letak untuk UI 2D dan spasial tanpa kehilangan konteks antar-file. Hal ini memudahkan Anda untuk berbagi hal-hal seperti arsitektur aplikasi yang ada antara XR dan faktor bentuk lainnya tanpa perlu mengangkat status melalui seluruh hierarki UI atau mendesain ulang aplikasi.
Untuk informasi selengkapnya, baca artikel tentang menambahkan subspace ke aplikasi.
Tentang komponen spasial
Composable subspace: Komponen ini hanya dapat dirender di subspace.
Elemen ini harus diapit dalam Subspace
atau setSubspaceContent
sebelum
ditempatkan dalam tata letak 2D. SubspaceModifier
memungkinkan Anda menambahkan
atribut seperti kedalaman, offset, dan pemosisian ke composable subspace.
- Catatan tentang pengubah subspace: Perhatikan dengan cermat urutan
SubspaceModifier
API.- Offset harus terjadi terlebih dahulu dalam rantai pengubah
- Dapat dipindahkan dan diubah ukurannya harus terjadi terakhir
- Rotasi harus diterapkan sebelum penskalaan
Komponen spasial lainnya tidak perlu dipanggil di dalam subruang. Elemen ini terdiri dari elemen 2D konvensional yang digabungkan dalam penampung spasial. Elemen ini dapat digunakan dalam tata letak 2D atau 3D jika ditentukan untuk keduanya. Jika pemosisian spasial tidak diaktifkan, fitur yang diposisikan secara spasial akan diabaikan dan akan kembali ke versi 2D-nya.
Membuat panel spasial
SpatialPanel
adalah composable subspace yang memungkinkan Anda menampilkan konten aplikasi. Misalnya, Anda dapat menampilkan pemutaran video, gambar diam, atau konten lainnya di
panel spasial.
Anda dapat menggunakan SubspaceModifier
untuk mengubah ukuran, perilaku, dan pemosisian
panel spasial, seperti yang ditunjukkan dalam contoh berikut.
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
)
}
}
Poin penting tentang kode
- Catatan tentang pengubah subspace: Perhatikan dengan cermat urutan
SubspaceModifier
API.- Offset harus terjadi terlebih dahulu dalam rantai pengubah.
- Pengubah yang dapat dipindahkan dan diubah ukurannya harus terjadi terakhir.
- Rotasi harus diterapkan sebelum skala.
- Karena
SpatialPanel
API adalah composable subspace, Anda harus memanggilnya di dalamSubspace
atausetSubspaceContent
. Memanggilnya di luar subruang akan menampilkan pengecualian. - Izinkan pengguna mengubah ukuran atau memindahkan panel dengan menambahkan
.movable
atau.resizable
SubspaceModifier
. - Lihat panduan desain panel spasial kami untuk mengetahui detail tentang ukuran dan pemosisi. Lihat dokumentasi referensi kami untuk mengetahui detail selengkapnya tentang penerapan kode.
Membuat orbiter
Orbiter adalah komponen UI spasial. Panel ini dirancang untuk dilampirkan ke panel spasial yang sesuai, dan berisi navigasi serta item tindakan kontekstual yang terkait dengan panel spasial tersebut. Misalnya, jika telah membuat panel spasial untuk menampilkan konten video, Anda dapat menambahkan kontrol pemutaran video di dalam orbiter.
Seperti yang ditunjukkan dalam contoh berikut, panggil orbiter di dalam SpatialPanel
untuk
menggabungkan kontrol pengguna seperti navigasi. Tindakan ini akan mengekstraknya dari tata letak 2D
dan melampirkan ke panel spasial sesuai dengan konfigurasi Anda.
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
)
}
}
}
}
Poin penting tentang kode
- Catatan tentang Pengubah Subruang: Perhatikan dengan cermat urutan
SubspaceModifier
API.- Offset harus terjadi terlebih dahulu dalam rantai pengubah
- Dapat dipindahkan dan diubah ukurannya harus terjadi terakhir
- Rotasi harus diterapkan sebelum penskalaan
- Karena orbiter adalah komponen UI spasial, kode dapat digunakan kembali dalam tata letak 2D atau 3D. Dalam tata letak 2D, aplikasi Anda hanya merender konten di dalam orbiter dan mengabaikan orbiter itu sendiri.
- Lihat panduan desain kami untuk informasi selengkapnya tentang cara menggunakan dan mendesain orbiter.
Menambahkan beberapa panel spasial ke tata letak spasial
Anda dapat membuat beberapa panel spasial dan menempatkannya dalam
SpatialLayout
menggunakan SpatialRow
,
SpatialColumn
, SpatialBox
, dan
SpatialLayoutSpacer
.
Contoh kode berikut menunjukkan cara melakukannya.
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
)
}
}
Poin penting tentang kode
SpatialRow
,SpatialColumn
,SpatialBox
, danSpatialLayoutSpacer
adalah composable subspace dan harus ditempatkan dalam subspace.- Gunakan
SubspaceModifier
untuk menyesuaikan tata letak. - Untuk tata letak dengan beberapa panel dalam satu baris, sebaiknya tetapkan radius kurva
825dp menggunakan
SubspaceModifier
sehingga panel akan mengelilingi pengguna Anda. Lihat panduan desain kami untuk mengetahui detailnya.
Menggunakan volume untuk menempatkan objek 3D dalam tata letak
Untuk menempatkan objek 3D dalam tata letak, Anda harus menggunakan composable subspace yang disebut volume. Berikut adalah contoh cara melakukannya.
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
}
}
}
}
}
Poin penting tentang kode
- Catatan tentang Pengubah Subruang: Perhatikan dengan cermat urutan
SubspaceModifier
API.- Offset harus terjadi terlebih dahulu dalam rantai pengubah
- Dapat dipindahkan dan diubah ukurannya harus terjadi terakhir
- Rotasi harus diterapkan sebelum penskalaan
- Lihat Menambahkan konten 3D untuk lebih memahami cara memuat konten 3D dalam volume.
Menambahkan komponen UI spasial lainnya
Komponen UI spasial dapat ditempatkan di mana saja dalam hierarki UI aplikasi Anda. Elemen ini dapat digunakan kembali di UI 2D Anda, dan atribut spasialnya hanya akan terlihat saat kemampuan spasial diaktifkan. Hal ini memungkinkan Anda menambahkan elevasi ke menu, dialog, dan komponen lainnya tanpa perlu menulis kode dua kali. Lihat contoh UI spasial berikut untuk lebih memahami cara menggunakan elemen ini.
Komponen UI |
Saat spasialisasi diaktifkan |
Di lingkungan 2D |
---|---|---|
|
Panel akan sedikit didorong kembali dalam kedalaman z untuk menampilkan dialog yang ditinggikan |
Melakukan fallback ke 2D |
|
Panel akan sedikit didorong ke belakang dalam kedalaman z untuk menampilkan pop-up yang ditinggikan |
Melakukan fallback ke |
|
|
Menampilkan tanpa elevasi spasial. |
SpatialDialog
Ini adalah contoh dialog yang terbuka setelah penundaan singkat. Saat
SpatialDialog
digunakan, dialog akan muncul pada kedalaman z yang sama dengan panel
spasial, dan panel akan didorong kembali sebesar 125dp saat spasialisasi diaktifkan.
SpatialDialog
masih dapat digunakan jika spatialisasi juga tidak diaktifkan, dan
akan kembali ke versi 2D-nya: 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")
}
}
}
}
}
Poin penting tentang kode
- Ini adalah contoh
SpatialDialog
. PenggunaanSpatialPopUp
danSpatialElevation
akan sangat mirip. Lihat referensi API untuk mengetahui detail selengkapnya.
Membuat panel dan tata letak kustom
Untuk membuat panel kustom yang tidak didukung oleh Compose untuk XR, Anda dapat bekerja
langsung dengan PanelEntities
dan grafik tampilan menggunakan
SceneCore
API.