Permukaan di Jetpack Compose Glimmer

Perangkat XR yang kompatibel
Panduan ini membantu Anda membangun pengalaman untuk jenis perangkat XR ini.
Kacamata Tampilan

Di Jetpack Compose Glimmer, komponen surface adalah blok penyusun dasar yang mewakili area visual yang berbeda atau batas fisik untuk komponen seperti tombol dan kartu.

Surface bertanggung jawab atas properti visual dan fisik berikut:

  • Pemangkasan: Memangkas turunannya ke bentuk yang ditentukan.
  • Batas: Menggambar batas dalam untuk menekankan batas komponen. Saat difokuskan, batas akan digambar lebih lebar dengan sorotan yang difokuskan.
  • Latar belakang: Menerapkan warna latar belakang ke area permukaan.
  • Efek kedalaman: Merender DepthEffect bayangan berdasarkan status komponen (seperti default versus difokuskan).
  • Warna Konten: Menyediakan warna untuk teks dan ikon di dalam permukaan, yang dihitung secara default dari warna latar belakang.
  • Status Interaksi: Menggambar overlay yang ditekan saat permukaan ditekan dan batas yang lebih lebar dengan sorotan saat difokuskan.

Contoh: Membuat permukaan

Kode berikut membuat permukaan dengan pemangkasan, latar belakang, dan batas default:

@Composable
fun SurfaceSample() {
    Box(Modifier.surface().padding(horizontal = 24.dp, vertical = 20.dp)) {
        Text("This is a surface")
    }
}

Interaction and Focus

Surfaces aren't focusable by default, so users can't interact with them. In most cases, surfaces should be interactive to let users consistently move focus and navigate between components. You can use the Compose focusable modifer for surfaces that are only intended to be focusable, or the Compose clickable modifer and other modifiers for surfaces that require actions.

You can create a focusable surface by combining a surface modifier with the focusable modifier:

@Composable
fun FocusableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        Modifier.surface(
                // Provide the same interaction source here and to focusable to make sure that
                // surface appears focused when interacted with.
                interactionSource = interactionSource
            )
            .focusable(interactionSource = interactionSource)
            .padding(horizontal = 24.dp, vertical = 20.dp)
    ) {
        Text("This is a focusable surface")
    }
}

Key points about the code

  • Shared interaction source: Both .surface() and .focusable() must share the same interactionSource. This lets the surface react to focus changes.

Similarly, you can create a clickable surface:

@Composable
fun ClickableSurfaceSample() {
    val interactionSource = remember { MutableInteractionSource() }
    Box(
        Modifier.surface(
                // Provide the same interaction source here and to clickable to make sure that
                // surface appears focused and pressed when interacted with
                interactionSource = interactionSource
            )
            .clickable(interactionSource = interactionSource, onClick = {})
            .padding(horizontal = 24.dp, vertical = 20.dp)
    ) {
        Text("This is a clickable surface")
    }
}

Poin-poin penting tentang kode

  • Sumber interaksi bersama: Keduanya .surface() dan .clickable() harus menggunakan interactionSource yang sama. Hal ini memastikan bahwa status visual (seperti tekan atau fokus) disinkronkan, sehingga permukaan dapat bereaksi secara visual terhadap input pengguna.

  • Pengurutan pengubah: Urutan pengubah sangat penting. Karena .surface() memangkas tata letak, menempatkannya sebelum .clickable() memastikan target sentuh dibatasi ke bentuk permukaan. Jika .clickable() muncul terlebih dahulu, area interaksi mungkin meluas di luar batas komponen yang terlihat dan dipangkas.

SurfaceDepthEffect

Class SurfaceDepthEffect mengelola transisi bayangan antara status interaksi:

  • depthEffect: Efek bayangan yang digunakan saat permukaan dalam status default.
  • focusedDepthEffect: Efek bayangan yang digunakan saat permukaan difokuskan.