Mendukung konten yang dapat diskalakan oleh pengguna

Terapkan gestur cubit untuk melakukan zoom guna mendukung konten yang dapat diskalakan di aplikasi Anda. Ini adalah metode standar yang konsisten di seluruh platform untuk meningkatkan aksesibilitas, sehingga pengguna dapat menyesuaikan ukuran teks dan elemen UI secara intuitif agar sesuai dengan kebutuhan mereka. Aplikasi Anda dapat menentukan perilaku penskalaan kustom dengan kontrol terperinci dan perilaku kontekstual yang menawarkan pengalaman yang sering kali ditemukan pengguna lebih cepat daripada fitur tingkat sistem seperti pembesaran layar.

Memilih strategi penskalaan

Strategi yang dibahas dalam panduan ini menyebabkan UI diatur ulang dan disusun ulang agar sesuai dengan lebar layar. Hal ini memberikan manfaat aksesibilitas yang signifikan dengan menghilangkan kebutuhan untuk menggeser secara horizontal dan gerakan "zig-zag" yang menjengkelkan yang diperlukan untuk membaca baris teks yang panjang.

Bacaan Lebih Lanjut: Riset mengonfirmasi bahwa bagi pengguna dengan gangguan penglihatan, penyesuaian tata letak konten secara signifikan lebih mudah dibaca dan dinavigasi daripada antarmuka yang memerlukan penggeseran dua dimensi. Untuk mengetahui detail selengkapnya, lihat Perbandingan Konten Pan-and-Scan dan Konten yang Dapat Diatur Ulang di Perangkat Seluler.

Menskalakan semua elemen atau hanya elemen teks

Tabel berikut menunjukkan efek visual dari setiap strategi penskalaan.

Strategi Penskalaan kepadatan Penskalaan font

Perilaku

Menskalakan semuanya secara proporsional. Konten akan diatur ulang agar sesuai dengan penampungnya, sehingga pengguna tidak perlu menggeser secara horizontal untuk melihat semua konten.

Hanya memengaruhi elemen teks. Tata letak keseluruhan dan komponen non-teks tetap berukuran sama.

Apa yang Dapat Diskalakan

Semua elemen visual: Teks, komponen (tombol, ikon), gambar, dan jarak tata letak (padding, margin)

Hanya teks

Demonstrasi

Rekomendasi

Setelah melihat perbedaan visual, tabel berikut membantu Anda mempertimbangkan kompromi dan memilih strategi terbaik untuk konten Anda.

Jenis UI

Strategi yang direkomendasikan

Penalaran

Tata letak yang mengutamakan bacaan

Contoh: Artikel berita, aplikasi pesan

Penskalaan kepadatan atau font

Penskalaan kepadatan lebih disukai untuk menskalakan seluruh area konten, termasuk gambar inline.

Penskalaan font adalah alternatif langsung jika hanya teks yang perlu diskalakan.

Tata letak terstruktur secara visual

Contoh: App store, feed media sosial

Penskalaan kepadatan

Mempertahankan hubungan visual antara gambar dan teks dalam carousel atau petak. Sifat tata ulang menghindari penggeseran horizontal, yang akan bertentangan dengan elemen scrolling bertingkat.

Mendeteksi gestur penskalaan di Jetpack Compose

Untuk mendukung konten yang dapat diskalakan pengguna, Anda harus mendeteksi gestur multi-sentuh terlebih dahulu. Di Jetpack Compose, Anda dapat melakukannya menggunakan Modifier.transformable.

Pengubah transformable adalah API tingkat tinggi yang menyediakan delta zoomChange sejak peristiwa gestur terakhir. Hal ini menyederhanakan logika update status menjadi akumulasi langsung (misalnya, scale *= zoomChange), sehingga ideal untuk strategi penskalaan adaptif yang dibahas dalam panduan ini.

Contoh penerapan

Contoh berikut menunjukkan cara menerapkan strategi penskalaan kepadatan dan penskalaan font.

Penskalaan kepadatan

Pendekatan ini menskalakan density dasar area UI. Akibatnya, semua pengukuran berbasis tata letak—termasuk padding, jarak, dan ukuran komponen—akan diskala, seolah-olah ukuran atau resolusi layar telah berubah. Karena ukuran teks juga bergantung pada kepadatan, ukuran teks juga diskalakan secara proporsional. Strategi ini efektif jika Anda ingin memperbesar semua elemen secara seragam dalam area tertentu, sambil mempertahankan ritme visual dan proporsi UI secara keseluruhan.

private class DensityScalingState(
    // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x.
    private val minScale: Float = 0.75f,
    private val maxScale: Float = 3.5f,
    private val currentDensity: Density
) {
    val transformableState = TransformableState { zoomChange, _, _ ->
        scaleFactor.floatValue =
            (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale)
    }
    val scaleFactor = mutableFloatStateOf(1f)
    fun scaledDensity(): Density {
        return Density(
            currentDensity.density * scaleFactor.floatValue,
            currentDensity.fontScale
        )
    }
}

Penskalaan font

Strategi ini lebih bertarget, hanya mengubah faktor fontScale. Hasilnya adalah hanya elemen teks yang bertambah besar atau mengecil, sementara semua komponen tata letak lainnya—seperti penampung, padding, dan ikon—tetap berukuran tetap. Strategi ini cocok untuk meningkatkan keterbacaan teks di aplikasi yang banyak digunakan untuk membaca.

class FontScaleState(
    // Note: For accessibility, typical min/max values are ~0.75x and ~3.5x.
    private val minScale: Float = 0.75f,
    private val maxScale: Float = 3.5f,
    private val currentDensity: Density
) {
    val transformableState = TransformableState { zoomChange, _, _ ->
        scaleFactor.floatValue =
            (scaleFactor.floatValue * zoomChange).coerceIn(minScale, maxScale)
    }
    val scaleFactor = mutableFloatStateOf(1f)
    fun scaledFont(): Density {
        return Density(
            currentDensity.density,
            currentDensity.fontScale * scaleFactor.floatValue
        )
    }
}

UI demo bersama

Composable DemoCard bersama ini digunakan oleh kedua contoh sebelumnya untuk menyoroti perilaku penskalaan yang berbeda.

@Composable
private fun DemoCard() {
    Card(
        modifier = Modifier
            .width(360.dp)
            .padding(16.dp),
        shape = RoundedCornerShape(12.dp)
    ) {
        Column(
            modifier = Modifier.padding(16.dp),
            verticalArrangement = Arrangement.spacedBy(16.dp)
        ) {
            Text("Demo Card", style = MaterialTheme.typography.headlineMedium)
            var isChecked by remember { mutableStateOf(true) }
            Row(verticalAlignment = Alignment.CenterVertically) {
                Text("Demo Switch", Modifier.weight(1f), style = MaterialTheme.typography.bodyLarge)
                Switch(checked = isChecked, onCheckedChange = { isChecked = it })
            }
            Row(verticalAlignment = Alignment.CenterVertically) {
                Icon(Icons.Filled.Person, "Icon", Modifier.size(32.dp))
                Spacer(Modifier.width(8.dp))
                Text("Demo Icon", style = MaterialTheme.typography.bodyLarge)
            }
            Row(
                Modifier.fillMaxWidth(),
                horizontalArrangement = Arrangement.SpaceBetween
            ) {
                Box(
                    Modifier
                        .width(100.dp)
                        .weight(1f)
                        .height(80.dp)
                        .background(Color.Blue)
                )
                Box(
                    Modifier
                        .width(100.dp)
                        .weight(1f)
                        .height(80.dp)
                        .background(Color.Red)
                )
            }
            Text(
                "Demo Text: Lorem ipsum dolor sit amet, consectetur adipiscing elit," +
                    " sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
                style = MaterialTheme.typography.bodyMedium,
                textAlign = TextAlign.Justify
            )
        }
    }
}

Tips dan pertimbangan

Untuk menciptakan pengalaman yang lebih baik dan mudah diakses, pertimbangkan rekomendasi berikut:

  • Pertimbangkan untuk menawarkan kontrol skala non-gestur: Beberapa pengguna mungkin mengalami kesulitan dengan gestur. Untuk mendukung pengguna ini, pertimbangkan untuk menyediakan cara alternatif untuk menyesuaikan atau mereset skala yang tidak bergantung pada gestur.
  • Bangun untuk semua skala: Uji UI Anda terhadap penskalaan dalam aplikasi dan setelan font atau tampilan di seluruh sistem. Pastikan tata letak aplikasi Anda beradaptasi dengan benar tanpa merusak, tumpang-tindih, atau menyembunyikan konten. Pelajari lebih lanjut cara membuat tata letak adaptif.