Mempelajari Dasar-Dasar Android XR: Bagian 1 - Ruang dan Panel Spasial

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

Yang akan Anda butuhkan

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

  1. Kode untuk codelab ini dapat ditemukan di direktori xr-fundamentals dalam repositori GitHub xr-codelabs. Untuk meng-clone repositori, jalankan perintah berikut:
git clone https://github.com/android/xr-codelabs.git
  1. Atau, Anda dapat mendownload repositori sebagai file ZIP:

Membuka project

  • Setelah memulai Android Studio, impor project dengan memilih direktori xr-fundamentals/start saja. Direktori xr-fundamentals/part1 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.

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

d779257a53898d36.jpeg

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

c572cdee69669a23.jpeg

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

  1. 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.
  2. 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

  1. Setelah membuka Pengelola Perangkat, pilih XR di kolom Category di sisi kiri jendela. Kemudian, pilih profil hardware XR Device dari daftar lalu klik Next.

7a5f6b9c1766d837.png

  1. 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.
  2. Jalankan aplikasi di AVD yang baru saja dibuat.

51a6b3eb02916d74.png

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.

  1. Buat file baru, ToggleSpaceButton.kt di paket com.example.android.xrfundamentals.ui.component lalu 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
        )
    }
}
  1. Tambahkan tombol sebagai tindakan di TopAppBar saat 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:

  • LocalSpatialConfiguration adalah 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.
  • LocalSpatialCapabilities adalah 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.

5eec781e78280eda.gif

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:

8969b8fd2a79a669.gif

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.

c3db4b5ec6f3b39e.gif

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.

34936c6d0d82adb8.gif

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.

2be1a054de7a8106.png

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()
)

466c1154c0e1fda3.gif

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()
)

330b6a4d1a688a72.gif

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

Tantangan

  • Gunakan parameter tambahan yang tersedia untuk pengubah resizable dan movable.
  • Tambahkan panel tambahan.
  • Gunakan komponen spasial lain seperti dialog spasial

Dokumen referensi