1. Sebelum memulai
Yang akan Anda pelajari
- Pengalaman pengguna unik yang dapat terwujud berkat Android XR.
- Cara mengoptimalkan aplikasi untuk headset Android XR menggunakan library Jetpack Compose XR.
- Cara menggunakan elemen UI dari library Jetpack Compose 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 terbaru.
- 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.
- Pengalaman menggunakan mode dan panel spasial Android XR, misalnya, dengan menyelesaikan codelab Mempelajari dasar-dasar Android XR: Bagian 1 - Mode dan Panel Spasial.
Yang akan Anda bangun
Dalam codelab ini, Anda akan mengoptimalkan aplikasi lebih lanjut dengan beberapa fitur XR yang ada dengan menambahkan elemen UI mengambang dan menyesuaikan lingkungan virtual yang mengelilingi pengguna saat menggunakan aplikasi.
Titik awal | Hasil akhir |
2. Memulai persiapan
Mendapatkan kode
- Kode untuk codelab ini dapat ditemukan di direktori
xr-fundamentals
dalam 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 direktori
xr-fundamentals/part1
. Direktorixr-fundamentals/part2
berisi 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.
- Jika Anda belum mengikuti codelab pertama atau belum menggunakan emulator Android XR, ikuti langkah-langkah di Menjalankan aplikasi di emulator Android XR untuk menjalankan aplikasi.
3. Mempelajari konsep XR: Orbiter
Orbiter adalah elemen UI mengambang yang tersedia dalam mode Ruang Penuh yang biasanya digunakan untuk mengontrol konten dalam panel spasial atau entitas lain tempat orbitnya ditambatkan. Dengan menggunakan orbiter untuk kontrol konten, konten akan memiliki lebih banyak ruang, yang berarti pengguna dapat dengan cepat mengakses fitur yang terdapat dalam orbiter saat konten utama tetap terlihat. Orbiter memberi Anda fleksibilitas untuk mengintegrasikan komponen UI yang ada (seperti menu navigasi) atau membuat komponen baru.
Selain itu, Orbiter API memungkinkan Anda merender konten orbiter seperti biasa saat berjalan dalam mode Ruang Utama atau di perangkat non-XR dan otomatis membaginya menjadi orbiter saat berjalan dalam mode Ruang Penuh.
Dalam mode Ruang Utama, kolom samping navigasi ini dirender dalam panel aplikasi utama. | Dalam mode Ruang Penuh, kolom samping navigasi dibagi menjadi orbiter yang terkait ke panel utama. |
Pada tahap ini, aplikasi berisi tombol di panel aplikasi atas untuk beralih antara mode Ruang Utama dan mode Ruang Penuh. Tombol ini adalah contoh sempurna dari kontrol yang dapat ditempatkan dalam orbiter saat berjalan dalam mode Ruang Penuh, karena memindahkan kontrol untuk mengorbit panel utama akan membantu kontrol terlihat jelas sekaligus secara visual menunjukkan bahwa kontrol akan menciutkan konten aplikasi ke dalam panel tersebut saat diklik.
Status saat ini | Yang akan Anda terapkan |
Untuk mempelajari lebih lanjut pertimbangan desain untuk orbiter, lihat UI Spasial.
4. Menambahkan Orbiter
Menggabungkan tombol mode ruang
Untuk mengubah tombol mode ruang menjadi orbiter, gabungkan composable ToggleSpaceModeButton
dalam composable Orbiter
.
ui/component/XRFundamentalsTopAppBar .kt
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.ui.Alignment
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.EdgeOffset
import androidx.xr.compose.spatial.Orbiter
import androidx.xr.compose.spatial.OrbiterEdge
import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape
...
Orbiter(
position = OrbiterEdge.Top,
alignment = Alignment.End,
offset = EdgeOffset.inner(16.dp),
shape = SpatialRoundedCornerShape(
CornerSize(percent = 100)
)
) {
ToggleSpaceModeButton()
}
Sekarang, jalankan aplikasi: Saat berjalan dalam mode Ruang Utama, Anda akan melihat bahwa tidak ada yang berubah. Namun, saat mengklik tombol dan aplikasi memasuki mode Ruang Penuh, Anda akan melihat bahwa tombol tidak lagi di panel aplikasi atas, tetapi ada di tepi kanan atas panel spasial utama.
Orbiter dikaitkan ke panel spasial utama karena merupakan entity spasial induk terdekat di hierarki UI. Posisi persis orbiter yang terkait dengan panel spasial utama ditentukan oleh parameter position
, alignment
, dan offset
. Coba ubah parameter ini untuk melihat rentang perilaku yang didukungnya.
Mode Ruang Utama | Mode Ruang Penuh |
5. Mempelajari konsep XR: Lingkungan spasial
Menggunakan Orbiter
untuk menyesuaikan posisi di ruang 3D elemen UI adalah cara yang bagus untuk meningkatkan pengalaman pengguna di perangkat XR. Anda dapat meningkatkan pengalaman lebih lanjut dengan menyesuaikan lingkungan spasial tempat pengguna berada saat menggunakan aplikasi Anda.
Lingkungan spasial dapat menggabungkan aset kedalaman, tekstur, dan geometri 3D untuk menciptakan pengalaman yang kaya dan imersif secara visual. Hal ini dilakukan melalui penggunaan gambar skybox bulat (dalam format EXR) untuk memberikan latar belakang panorama yang jauh dan/atau aset geometri (dalam format glTF) untuk memberikan elemen latar depan dan latar tengah yang dapat menyatu dengan skybox. Misalnya, aplikasi streaming video dapat menggunakan skybox malam dengan glTF bioskop drive-in dengan layar proyeksi dan mobil. Saat membuat aset untuk menetapkan lingkungan spasial pengguna, pastikan aset Anda mencapai resolusi berkualitas tinggi sekaligus mempertahankan ukuran file yang wajar. Lihat Mengoptimalkan aset lingkungan untuk mengetahui informasi selengkapnya.
Selain itu, opasitas lingkungan spasial dapat dikontrol. Hal ini memungkinkan streaming video dunia nyata menembus dan menyatu dengan lingkungan virtual, yang dapat membantu pengguna mempertahankan posisinya.
Pada langkah berikutnya, Anda akan menambahkan aset geometri ke aplikasi dan membuat menu untuk memungkinkan pengguna memilih lingkungan mereka.
Untuk mengetahui semua detail tentang mendesain dan menerapkan lingkungan spasial, lihat Lingkungan spasial dan Menambahkan lingkungan spasial ke aplikasi Anda.
6. Mengizinkan pengguna mengubah lingkungan spasial
Cara aplikasi mengontrol lingkungan spasial
Sebelum memulai, sebaiknya pahami cara aplikasi dapat mengontrol lingkungan spasial.
Tidak seperti konten dalam panel, aplikasi tidak mengontrol lingkungan secara langsung. Sebagai gantinya, aplikasi dapat berinteraksi dengan sesi SceneCore untuk memberikan preferensi bagi lingkungan yang ingin digunakan sistem. Preferensi ini diwakili oleh SpatialEnvironmentPreference
, yang terdiri dari gambar EXR skybox dan/atau glTF geometri. Hal yang terjadi saat aplikasi memberikan preferensi bergantung pada kemampuan aplikasi saat menetapkan preferensi. Jika aplikasi Anda memiliki kemampuan untuk mengubah lingkungan, sistem akan segera menggunakannya. Jika aplikasi tidak memiliki kemampuan tersebut, preferensi akan diterapkan saat aplikasi Anda mendapatkan kemampuan tersebut.
Misalnya, aplikasi umumnya tidak memiliki kemampuan untuk mengubah lingkungan saat berjalan dalam mode Ruang Utama, tetapi umumnya dapat melakukannya saat berjalan dalam mode Ruang Penuh. Jadi, jika Anda mengizinkan pengguna menetapkan preferensi lingkungan saat dalam mode Ruang Utama, preferensi tersebut umumnya tidak akan berlaku hingga aplikasi Anda berjalan dalam mode Ruang Penuh.
Menambahkan dependensi pada library XR SceneCore
Untuk mulai mengubah lingkungan spasial, tambahkan dependensi pada library XR SceneCore, yang akan Anda gunakan untuk memuat aset lingkungan dan menetapkan preferensi lingkungan. Anda juga harus menambahkan dependensi pada artefak kotlinx-coroutines-guava
, karena beberapa API untuk memuat aset menggunakan jenis data ListenableFuture
.
libs.version.toml
[versions]
...
xrSceneCore = "1.0.0-alpha04"
kotlinxCoroutinesGuava = "1.10.2"
[libraries]
...
androidx-xr-scenecore = { group = "androidx.xr.scenecore", name = "scenecore", version.ref = "xrSceneCore"}
jetbrains-kotlinx-coroutines-guava = {group = "org.jetbrains.kotlinx", name="kotlinx-coroutines-guava", version.ref = "kotlinxCoroutinesGuava"}
app/build.gradle.kts
dependencies {
...
implementation(libs.androidx.xr.scenecore)
implementation(libs.jetbrains.kotlinx.coroutines.guava)
...
}
Menambahkan aset lingkungan ke project Anda
Untuk menentukan preferensi lingkungan yang unik, Anda memerlukan skybox dan/atau aset geometri. Untuk codelab ini, Anda hanya akan menggunakan aset geometri green_hills_ktx2_mipmap.glb
, yang dapat Anda temukan di folder part2
yang berisi kode solusi atau di GitHub.
- Klik kanan modul aplikasi di jendela Project dalam Android Studio. Kemudian, pilih New > Folder > Assets Folder, lalu klik Finish untuk membuat folder.
- Tambahkan file GLB ke folder
app/src/main/assets
yang baru saja Anda buat.
Membuat model opsi lingkungan
Untuk menyederhanakan interaksi antara kode UI dan API sistem, Anda dapat membuat class data Kotlin untuk membuat model setiap opsi lingkungan.
- Klik kanan paket
com.example.android.xrfundamentals
di jendela Project, lalu pilih New > Package. Masukkancom.example.android.xrfundamentals.environment
sebagai nama paket. - Klik kanan pada paket tersebut, lalu pilih New > Kotlin Class/File. Masukkan
EnvironmentOption
sebagai nama, lalu klik jenis Data class. - Tambahkan kode berikut di file yang baru saja Anda buat:
EnvironmentOption.kt
data class EnvironmentOption(val name: String, val skyboxPath: String?, val geometryPath: String?)
val DEFAULT_ENVIRONMENT = EnvironmentOption("Default", null, null)
val ENVIRONMENT_OPTIONS = listOf(
DEFAULT_ENVIRONMENT,
EnvironmentOption("Green Hills", null, "green_hills_ktx2_mipmap.glb")
)
Menambahkan helper untuk membuat aset pemuatan dan menampilkan SpatialEnvironmentPreference
Selanjutnya, Anda dapat menambahkan metode bantuan ke class data untuk memudahkan konversi EnvironmentOption
ke SpatialEnvrionmentPreference
yang sesuai.
EnvironmentOption.kt
import androidx.xr.runtime.Session
import androidx.xr.scenecore.ExrImage
import androidx.xr.scenecore.GltfModel
import androidx.xr.scenecore.SpatialEnvironment
import kotlinx.coroutines.guava.await
...
data class EnvironmentOption(val name: String, val skyboxPath: String?, val geometryPath: String?) {
suspend fun toSpatialEnvironmentPreference(session: Session): SpatialEnvironmentPreference? {
if (skyboxPath == null && geometryPath == null) {
return null
} else {
val skybox = skyboxPath?.let {
ExrImage.create(session, it).await()
}
val geometry = geometryPath?.let {
GltfModel.create(session, it).await()
}
return SpatialEnvironmentPreference(skybox, geometry)
}
}
}
Ada beberapa hal yang perlu diperhatikan di sini:
- Jika skybox dan geometri bernilai null, null akan ditampilkan untuk menunjukkan bahwa preferensi lingkungan sistem default harus digunakan. Lihat
setSpatialEnvironmentPreference
untuk mengetahui informasi selengkapnya. - Resource
skybox
dangeometry
dibuat secara asinkron karena aset ini sering kali cukup besar dan memerlukan waktu untuk dibaca ke dalam memori. Di aplikasi produksi, sebaiknya pertimbangkan untuk meng-cache aset ini di memori jika sering beralih lingkungan.
Mengimplementasikan UI pemilihan lingkungan
Untuk menerapkan UI, Anda akan menambahkan orbiter kedua yang berputar melalui opsi lingkungan saat diklik.
Menambahkan orbiter
- Klik kanan modul
app
di jendela Project, lalu pilih New > Vector Asset. Klik kolom Clip art, lalu cari dan pilih asetlandscape
(dari grup ikon Filled), lalu klik OK, lalu Next untuk membuat aset. - Klik kanan paket
com.example.android.xrfundamentals.ui.component
, lalu pilih New > Kotlin Class/File. MasukkanEnvironmentSelectionOrbiter
sebagai nama dan klik jenis File. - Dalam file yang baru saja Anda buat, tambahkan implementasi composable
EnvironmentSelectionOrbiter
berikut
EnvironmentSelectionOrbiter.kt
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import androidx.xr.compose.spatial.EdgeOffset
import androidx.xr.compose.spatial.Orbiter
import androidx.xr.compose.spatial.OrbiterEdge
import androidx.xr.compose.subspace.layout.SpatialRoundedCornerShape
import com.example.android.xrfundamentals.R
@Composable
fun EnvironmentSelectionOrbiter(
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
) {
Orbiter(
position = OrbiterEdge.Top,
alignment = Alignment.Start,
offset = EdgeOffset.inner(16.dp),
shape = SpatialRoundedCornerShape(
CornerSize(100)
)
) {
FilledTonalIconButton(
modifier = modifier,
onClick = onClick,
) {
Icon(painterResource(R.drawable.baseline_landscape_24), "Show environment selection dialog")
}
}
}
- Terakhir, tambahkan
EnvironmentSelectionOrbiter
dalam panel spasial utama
XRFundamentalsApp.kt
import androidx.xr.compose.platform.LocalSpatialCapabilities
import com.example.android.xrfundamentals.ui.component.EnvironmentSelectionOrbiter
...
SpatialPanel(...) {
// Only show the environment selection orbiter if the app is actually able to
// change the environment
if (LocalSpatialCapabilities.current.isAppEnvironmentEnabled) {
EnvironmentSelectionOrbiter(
onClick = { TODO() }
)
}
...
}
Mengubah lingkungan saat orbiter diklik
Agar semuanya berfungsi, ada satu langkah terakhir, yaitu memanggil setSpatialEnvironmentPreference
di handler klik EnvironmentSelectionOrbiter
.
- Siapkan variabel untuk melacak opsi lingkungan saat ini (di luar
Subspace
sehingga status dipertahankan saat beralih antara mode Ruang Utama dan mode Ruang Penuh). Selain itu, buat variabel untuk sesi XR saat ini dan cakupan coroutine untuk memanggil helpertoSpatialEnvironmentPreference
XRFundamentalsApp.kt
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.rememberCoroutineScope
import androidx.xr.compose.platform.LocalSession
...
var currentEnvironmentOptionIndex by remember { mutableStateOf(0) }
Subspace {
val session = checkNotNull(LocalSession.current)
val scope = rememberCoroutineScope()
...
}
- Implementasikan callback
onClick
untuk memutar opsi lingkungan.
XRFundamentalsApp.kt
EnvironmentSelectionOrbiter(
onClick = {
scope.launch {
currentEnvironmentOptionIndex =
(currentEnvironmentOptionIndex + 1) % ENVIRONMENT_OPTIONS.size
session.scene.spatialEnvironment.setSpatialEnvironmentPreference(
ENVIRONMENT_OPTIONS[currentEnvironmentOptionIndex].toSpatialEnvironmentPreference(
session
)
)
}
}
)
Jalankan aplikasi Anda sekali lagi dan lihat, Anda dapat beralih antara Green Hills dan lingkungan default.
7. Selamat
Untuk terus mempelajari cara mengoptimalkan XR, lihat 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
- Temukan atau buat aset lingkungan tambahan dan tambahkan sebagai opsi.
- Ubah pengontrol lingkungan dan UI untuk memungkinkan pengguna menetapkan preferensi passthrough menggunakan
setPassthroughOpacityPreference
API. Perhatikan bahwa mengontrol passthrough dibatasi oleh kemampuan yang berbeda dengan mengubah aset lingkungan.