1. Sebelum memulai
Yang akan Anda pelajari
- Pengalaman pengguna unik yang dapat terwujud berkat faktor bentuk XR.
- Dasar-dasar cara menyesuaikan aplikasi Anda agar lebih optimal ketika dijalankan di headset Android XR. Misalnya, dengan menggunakan composable yang disediakan oleh Jetpack Compose untuk library XR.
- Cara menggunakan elemen UI yang sediakan oleh Compose untuk library XR.
- Tempat menemukan referensi untuk mempelajari lebih lanjut pembuatan aplikasi di Android XR.
Tidak termasuk dalam cakupan
- Panduan membangun aplikasi Android XR tanpa menggunakan Compose. Lihat Mengembangkan UI untuk Aplikasi berbasis View Android.
- Panduan membangun aplikasi Unity atau OpenXR untuk Android XR. Lihat Mengembangkan dengan Unity untuk Android XR dan Mengembangkan dengan OpenXR.
Yang akan Anda butuhkan
- Pratinjau Android Studio (Quail Canary 1 atau yang lebih baru).
- Komputer yang mampu menjalankan emulator Android XR.
- Pengalaman menggunakan Kotlin dan Jetpack Compose, misalnya, dengan menyelesaikan kursus Dasar-Dasar Android dengan Compose.
- Pengalaman membuat Perangkat Virtual Android dan menjalankan aplikasi di perangkat virtual tersebut.
Yang akan Anda bangun
Dalam codelab ini, Anda akan meningkatkan aplikasi layar tunggal dasar untuk memberikan pengalaman pengguna yang imersif melalui Android XR.
|
|
Titik awal | Hasil akhir |
2. Memulai persiapan
Mendapatkan kode
- Kode untuk codelab ini dapat ditemukan di direktori
xr-fundamentalsdalam repositori GitHubxr-codelabs. Untuk meng-clone repositori, jalankan perintah berikut:
git clone https://github.com/android/xr-codelabs.git
- Atau, Anda dapat mendownload repositori sebagai file ZIP:
Membuka project
- Setelah memulai Android Studio, impor project dengan memilih direktori
xr-fundamentals/startsaja. Direktorixr-fundamentals/part1berisi kode solusi yang dapat Anda rujuk kapan saja jika Anda mengalami kebuntuan atau hanya ingin melihat project lengkap.
Memahami kode
- Setelah membuka project di Android Studio, luangkan waktu untuk memeriksa kode awal.
3. Mempelajari konsep XR: Ruang dan Panel Spasial
Dalam codelab ini, Anda akan mempelajari dua konsep Android XR: ruang dan panel spasial. Anda juga akan mempelajari cara menerapkan konsep ini ke aplikasi yang berjalan di perangkat Android XR.
Ruang
Di perangkat Android XR, aplikasi berjalan di salah satu dari dua ruang: Ruang Utama atau Ruang Penuh.
Ruang Utama

Dalam mode Ruang Utama, beberapa aplikasi berjalan berdampingan sehingga pengguna dapat melakukan multitasking antaraplikasi. Aplikasi Android dapat berjalan dalam Ruang Utama tanpa modifikasi.
Ruang Penuh

Untuk mempelajari lebih lanjut ruang ini, lihat Ruang Utama dan Ruang Penuh.
Panel spasial
Panel spasial adalah elemen penampung yang berfungsi sebagai elemen penyusun fundamental dari aplikasi Android XR.
Saat berada dalam Ruang Utama, aplikasi Anda akan ditampung dalam satu panel agar menghasilkan pengalaman yang mirip dengan mode jendela desktop pada layar besar di perangkat Android.
Saat menjalankan Ruang Penuh, Anda dapat membagi konten aplikasi Anda menjadi satu atau beberapa panel agar dapat memberikan pengalaman yang imersif.
Untuk mempelajari lebih lanjut panel, lihat Panel spasial.
4. Menjalankan aplikasi di emulator Android XR
Sebelum mulai mengoptimalkan aplikasi untuk Android XR, Anda dapat menjalankan aplikasi di emulator Android XR untuk melihat tampilannya dalam Ruang Utama.
Menginstal image sistem Android XR
- Pertama, buka SDK Manager di Android Studio, lalu pilih tab SDK Platforms jika belum dipilih. Di pojok kanan bawah jendela SDK Manager, pastikan kotak Show package details dicentang.
- Di bawah bagian Android 14, instal image emulator Android XR ARM 64 v8a atau Android XR Intel x86_64. Image hanya dapat berjalan di komputer dengan arsitektur yang sama (x86/ARM) dengan image itu sendiri.
Membuat perangkat virtual Android XR
- Setelah membuka Pengelola Perangkat, pilih XR di kolom Category di sisi kiri jendela. Kemudian, pilih profil hardware XR Device dari daftar lalu klik Next.

- Di halaman berikutnya, pilih image sistem yang sudah Anda instal sebelumnya. Klik Next dan pilih opsi lanjutan yang Anda inginkan sebelum akhirnya membuat AVD dengan mengklik Finish.
- Jalankan aplikasi di AVD yang baru saja dibuat.

5. Menyiapkan dependensi
Sebelum Anda dapat mulai menambahkan fungsi khusus XR ke aplikasi, Anda harus menambahkan dependensi di Jetpack Compose untuk library XR, androidx.xr.compose:compose, yang berisi semua composable yang diperlukan untuk membangun pengalaman Android XR yang dirancang khusus untuk aplikasi Anda.
libs.version.toml
[versions]
...
xrCompose = "1.0.0-alpha13"
[libraries]
...
androidx-xr-compose = { group = "androidx.xr.compose", name = "compose", version.ref = "xrCompose" }
build.gradle.kts (Module :app)
dependencies {
...
implementation(libs.androidx.xr.compose)
...
}
Setelah mengupdate file ini, pastikan untuk melakukan sinkronisasi Gradle guna memastikan dependensi sudah didownload ke project Anda.
6. Memasuki Ruang Penuh
Untuk memanfaatkan fitur XR seperti panel, sebuah aplikasi harus berjalan dalam Ruang Penuh. Ada dua cara agar aplikasi dapat memasuki Ruang Penuh:
- Secara terprogram, seperti respons terhadap interaksi pengguna dalam aplikasi Anda
- Secara langsung saat diluncurkan dengan menambahkan perintah ke manifes aplikasi Anda.
Memasuki Ruang Penuh secara terprogram
Untuk memasuki Ruang Penuh secara terprogram, Anda dapat menyediakan kemampuan di UI agar pengguna dapat mengontrol ruang penggunaan aplikasi. Selain itu, Anda juga dapat memasuki mode Ruang Penuh jika dirasa momennya tepat sesuai dengan cara aplikasi Anda digunakan. Misalnya, memasuki Ruang Penuh saat mulai menonton konten video dan keluar dari mode tersebut saat pemutaran selesai.
Sederhananya, Anda dapat melakukan ini di awal dengan menambahkan tombol ke panel aplikasi di bagian atas untuk mengaktifkan/menonaktifkan ruang.
- Buat file baru,
ToggleSpaceButton.ktdi paketcom.example.android.xrfundamentals.ui.componentlalu tambahkan composable berikut:
ToggleSpaceButton.kt
package com.example.android.xrfundamentals.ui.component
import androidx.annotation.DrawableRes
import androidx.compose.material3.Icon
import androidx.compose.material3.FilledTonalIconButton
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 ToggleSpaceButton(
onHomeSpaceRequested: () -> Unit,
onFullSpaceRequested: () -> Unit,
modifier: Modifier = Modifier
) {
if (LocalSpatialCapabilities.current.isSpatialUiEnabled) {
ToggleSpaceButton(
modifier = modifier,
contentDescription = "Request Home Space",
iconResource = R.drawable.ic_home_space,
onClick = { onHomeSpaceRequested() }
)
} else {
ToggleSpaceButton(
modifier = modifier,
contentDescription = "Request Full Space",
iconResource = R.drawable.ic_full_space,
onClick = { onFullSpaceRequested() }
)
}
}
@Composable
fun ToggleSpaceButton(
contentDescription: String,
@DrawableRes iconResource: Int,
onClick: () -> Unit,
modifier: Modifier = Modifier
) {
FilledTonalIconButton(
modifier = modifier,
onClick = onClick
) {
Icon(
painterResource(iconResource),
contentDescription
)
}
}
- Tambahkan tombol sebagai tindakan di
TopAppBarsaat aplikasi berjalan di perangkat XR
XRFundamentalsTopAppBar.kt
import androidx.xr.compose.platform.LocalSpatialConfiguration
...
@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun XRFundamentalsTopAppBar(
onHomeSpaceRequested: () -> Unit,
onFullSpaceRequested: () -> Unit,
) {
TopAppBar(
title = { Text(stringResource(R.string.app_name)) },
actions = {
// Only show the space toggle if the device supports spatial UI
if (LocalSpatialConfiguration.current.hasXrSpatialFeature) {
ToggleSpaceButton(onHomeSpaceRequested, onFullSpaceRequested)
}
}
)
}
Kemudian, angkat interaksi onHomeSpaceRequested dan onFullSpaceRequested melalui XRFundamentalsApp dan ke MainActivity:
XRFundamentalsApp.kt
import androidx.xr.compose.spatial.Subspace
...
@Composable
fun XRFundamentalsApp(
...
onHomeSpaceRequested: () -> Unit,
onFullSpaceRequested: () -> Unit,
) {
Dari MainActivity, kita dapat memanggil metode ekstensi untuk meminta Ruang Utama dan Ruang Penuh
MainActivity.kt
...
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
setContent {
XRFundamentalsTheme {
XRFundamentalsApp(
onHomeSpaceRequested = {
lifecycleScope.launch {
requestHomeSpace()
}
},
onFullSpaceRequested = {
lifecycleScope.launch {
requestFullSpace()
}
},
)
}
}
}
}
Sekarang jalankan aplikasi.
|
|
Aplikasi berjalan dalam Ruang Utama saat diluncurkan. Ketuk tombol di kanan atas panel untuk beralih ke Ruang Penuh. | Aplikasi berjalan di Ruang Penuh. Perhatikan bahwa UI sistem untuk memperkecil/menutup aplikasi sudah tidak ada. Ketuk tombol di kanan atas panel untuk beralih kembali ke Ruang Utama. |
Cuplikan ini mencakup dua API yang perlu Anda ketahui:
LocalSpatialConfigurationadalah lokal komposisi yang menyediakan akses ke konfigurasi spasial saat ini di aplikasi. Selain sebagai metode untuk meminta pengubahan ruang, API ini mencakup informasi lain seperti ukuran volume yang menampung aplikasi.LocalSpatialCapabilitiesadalah lokal komposisi yang dapat digunakan untuk menentukan kemampuan spasial mana yang saat ini dapat digunakan aplikasi. Selain ruang (Ruang Utama atau Penuh), API ini mencakup kemampuan seperti audio spasial dan dukungan konten 3D.
Memasuki Ruang Penuh saat peluncuran
Untuk memberi instruksi agar OS memulai aktivitas dalam Ruang Penuh, Anda dapat menyertakan elemen <property> dengan atribut berikut dalam elemen <activity> yang sesuai. Tindakan ini direkomendasikan hanya jika pengguna kemungkinan besar tidak akan menggunakan aplikasi lain di saat yang sama ketika aplikasi Anda digunakan.
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>
Sekarang saat aplikasi diluncurkan, pengguna akan langsung diarahkan ke Ruang Penuh.

Sebelum melanjutkan, hapus elemen <property> yang disebutkan sebelumnya dari manifes agar aplikasi menggunakan perilaku default yaitu terbuka dalam Ruang Utama.
7. Membagi UI menjadi beberapa panel
Karena aplikasi Anda kini dapat masuk dan keluar dari Ruang Penuh, waktunya untuk memanfaatkannya lebih maksimal. Salah satu cara bagus untuk melakukan ini adalah dengan membagi konten aplikasi Anda menjadi beberapa panel untuk mengisi ruang, dan (secara opsional) memungkinkan pengguna memindahkan serta mengubah ukuran panel tersebut sesuai keinginan.
Menyematkan aplikasi Anda di subruang
Pertama-tama, tambahkan composable Subspace setelah composable Scaffold di composable XRFundamentalsApp. Subruang adalah partisi ruang 3D dalam aplikasi Anda tempat Anda dapat membangun tata letak 3D (mis. menambahkan panel spasial), menempatkan model 3D, dan menambahkan kedalaman pada konten 2D.
Saat berjalan di perangkat non-XR konten composable Subspace tidak pernah masuk ke Komposisi. Saat berjalan di perangkat XR, konten hanya masuk ke Komposisi saat aplikasi berjalan dalam Ruang Penuh.
XRFundamentalsApp.kt
import androidx.xr.compose.spatial.Subspace
...
HelloAndroidXRTheme {
Scaffold(...)
Subspace {
}
}
Sekarang jalankan aplikasi:

Jika aplikasi menyertakan composable Subspace, hanya kontennya yang akan ditampilkan. Artinya, saat Anda mengklik tombol untuk masuk ke Ruang Penuh, tidak ada lagi yang ditampilkan. Untuk memperbaikinya, Anda perlu menambahkan dua panel spasial di beberapa langkah selanjutnya, satu panel untuk menampung konten utama dan satu lagi untuk konten sekunder.
Menambahkan panel untuk konten utama
Untuk menampilkan konten utama dalam Ruang Penuh, tambahkan SpatialPanel dalam composable Subspace.
Karena panel ini adalah panel utama aplikasi, Anda dapat menyertakan Scaffold di dalamnya agar kontrol dalam panel aplikasi atas tetap ada.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.SpatialPanel
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.height
import androidx.xr.compose.subspace.layout.width
...
Subspace {
SpatialPanel(
modifier = SubspaceModifier
.width(1024.dp)
.height(800.dp)
) {
Scaffold(
topBar = { XRFundamentalsTopAppBar() }
) { innerPadding ->
Box(Modifier.padding(innerPadding)) {
PrimaryCard(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
)
}
}
}
}
Secara default, ukuran SpatialPanel ditentukan berdasarkan ukuran konten yang ada di dalamnya, tetapi juga dapat ditentukan dengan memberikan parameter SubspaceModifier. Pengubah subruang mirip dengan pengubah dan digunakan untuk mengubah komponen tata letak spasial seperti panel.
Karena konten panel spasial ini tidak menentukan ukurannya sendiri, SubspaceModifier harus disediakan agar panel memiliki lebar dan tinggi.

Menambahkan panel untuk konten sekunder
Karena aplikasi Anda sudah berjalan dalam Ruang Penuh dan menggunakan panel untuk menampilkan konten utama, sekarang waktunya untuk memindahkan konten sekunder ke panelnya sendiri. Perhatikan penggunaan Surface dalam panel spasial. Tanpa itu, tidak akan ada latar belakang untuk kartu sekunder karena panel spasial itu sendiri transparan (composable Scaffold menangani hal ini di langkah sebelumnya).
XRFundamentalsApp.kt
import androidx.compose.material3.Surface
...
Subspace {
SpatialPanel() { ... }
SpatialPanel(
modifier = SubspaceModifier
.width(340.dp)
.height(800.dp)
) {
Surface {
SecondaryCardList(
modifier = Modifier
.padding(16.dp)
.verticalScroll(rememberScrollState())
)
}
}
}
Sekarang jalankan aplikasi lagi. Sekilas, mungkin tampaknya panel kedua tidak muncul, tetapi sebenarnya muncul, hanya saja panel tersebut terhalangi oleh panel utama.

Mengatur tata letak panel dalam baris
Seperti halnya konten 2D, menggunakan baris dan kolom akan berguna untuk mengatur composable secara berdampingan tanpa terjadi tumpang-tindih. Saat menggunakan komponen spasial seperti panel, Anda dapat menggunakan composable SpatialRow, SpatialCurvedRow, dan SpatialColumn untuk melakukan ini.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.SpatialCurvedRow
...
Subspace {
SpatialCurvedRow(
curveRadius = 825.dp
) {
SpatialPanel(...) { ... }
SpatialPanel(...) { ... }
}
}
Jalankan aplikasi sekali lagi dan Anda akan melihat bahwa panel sudah tersusun dalam bentuk baris, berurutan satu per satu.
Karena Anda menggunakan composable SpatialCurvedRow, panel akan melengkung ke arah pengguna alih-alih berada di tempat yang sama (seperti yang terjadi dengan SpatialRow), sehingga memberikan pengalaman yang lebih melingkupi pengguna.

Membuat panel yang dapat diubah ukurannya
Untuk memberi pengguna kontrol atas tampilan aplikasi Anda, Anda dapat membuat panel dapat diubah ukurannya menggunakan pengubah resizable.
Secara default, panel yang dapat diubah ukurannya bisa diperkecil hingga nol atau diperbesar tanpa batas, jadi sebaiknya luangkan waktu untuk menetapkan parameter minimumSize dan maximumSize yang sesuai berdasarkan konten yang ditampungnya.
Lihat dokumentasi referensi untuk detail selengkapnya terkait semua parameter yang didukung pengubah resizable.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.resizable
...
SpatialPanel(
modifier = SubspaceModifier
...
.resizable()
)

Membuat panel dapat dipindah
Demikian pula, Anda dapat membuat panel dapat dipindah menggunakan MovePolicy.
XRFundamentalsApp.kt
import androidx.xr.compose.subspace.layout.SubspaceModifier
import androidx.xr.compose.subspace.layout.movable
...
SpatialPanel(
modifier = SubspaceModifier
...
.movable()
)

Lihat dokumentasi referensi untuk mengetahui detail selengkapnya terkait semua parameter yang didukung MovePolicy.
8. Memperbarui manifes
Setelah menambahkan fitur spasial ke aplikasi, Anda harus memperbarui manifes untuk menunjukkan bahwa aplikasi Anda mendukung fitur ini. Tindakan ini memungkinkan Google Play menandai aplikasi Anda sebagai aplikasi yang dirancang khusus untuk perangkat Android XR.
Untuk melakukannya, tambahkan elemen <uses-feature> berikut di file AndroidManifest.xml:
AndroidManifest.xml
<application ...>
...
<uses-feature android:name="android.software.xr.api.spatial" android:required="false"/>
...
</application>
Menggunakan nilai false untuk atribut android:required menunjukkan bahwa aplikasi menggunakan fitur tersebut jika tersedia, tetapi tidak mencegah aplikasi didistribusikan ke perangkat yang tidak memiliki fitur tersebut (misalnya, ponsel). Hal ini memungkinkan Anda melakukan distribusi ke perangkat ponsel dan XR dari jalur rilis seluler. Jika Anda ingin menggunakan jalur khusus XR, tetapkan android:required ke true.
9. Selamat
Untuk terus mempelajari cara mengoptimalkan Android XR, lihat codelab berikutnya, Mempelajari Dasar-Dasar Android XR: Bagian 2 - Orbiter dan Lingkungan Spasial, serta referensi dan latihan berikut:
Bacaan lebih lanjut
- Mendesain untuk XR membahas prinsip-prinsip dan praktik terbaik untuk digunakan saat membangun aplikasi untuk Android XR.
- Mengembangkan dengan Jetpack XR SDK berisi panduan teknis mengenai API dan alat yang dapat digunakan dalam membangun pengalaman Android XR.
- Halaman Pedoman kualitas aplikasi Android XR menjelaskan kriteria untuk membuat pengalaman pengguna yang baik.
- Pelajari lebih lanjut sampel Hello Android XR
Tantangan
- Gunakan parameter tambahan yang tersedia untuk pengubah
resizabledanmovable. - Tambahkan panel tambahan.
- Gunakan komponen spasial lain seperti dialog spasial


