Dukungan untuk berbagai ukuran tampilan memungkinkan akses ke aplikasi Anda oleh berbagai macam perangkat dan sejumlah besar pengguna.
Untuk mendukung ukuran tampilan sebanyak mungkin—baik layar perangkat yang berbeda maupun jendela aplikasi yang berbeda dalam mode multi-aplikasi—desain tata letak aplikasi Anda agar responsif dan adaptif. Tata letak responsif/adaptif memberikan pengalaman pengguna yang dioptimalkan terlepas dari ukuran tampilan, sehingga memungkinkan aplikasi Anda mengakomodasi ponsel, tablet, perangkat foldable, perangkat ChromeOS, orientasi potret dan lanskap, serta konfigurasi tampilan yang dapat diubah ukurannya seperti mode layar terpisah dan mode jendela desktop.
Tata letak responsif/adaptif berubah berdasarkan ruang tampilan yang tersedia. Perubahan berkisar dari penyesuaian tata letak kecil yang mengisi ruang (desain responsif) hingga mengganti satu tata letak dengan tata letak lain sepenuhnya sehingga aplikasi Anda dapat mengakomodasi berbagai ukuran tampilan dengan sebaik-baiknya (desain adaptif).
Sebagai toolkit UI deklaratif, Jetpack Compose sangat cocok untuk mendesain dan mengimplementasikan tata letak yang berubah secara dinamis untuk merender konten secara berbeda pada ukuran tampilan yang berbeda.
Keterampilan Android
Lihat di GitHubMembuat aplikasi Anda adaptif
adaptive keterampilan Android untuk memperbarui UI aplikasi Anda sehingga dapat beradaptasi dengan berbagai perangkat dan tampilan Android.android skills add adaptiveMembuat perubahan tata letak yang besar untuk composable tingkat konten secara eksplisit
Composable tingkat aplikasi dan tingkat konten menempati semua ruang tampilan yang tersedia untuk aplikasi Anda. Untuk jenis composable ini, sebaiknya ubah tata letak keseluruhan aplikasi Anda pada tampilan besar.
Hindari menggunakan nilai hardware fisik untuk membuat keputusan tata letak. Anda mungkin ingin membuat keputusan berdasarkan nilai nyata yang tetap (Apakah perangkat ini berupa tablet? Apakah layar fisik memiliki rasio aspek tertentu?), tetapi jawaban atas pertanyaan ini mungkin tidak berguna untuk menentukan ruang yang tersedia untuk UI Anda.
Pada tablet, aplikasi mungkin berjalan dalam mode multi-aplikasi, yang berarti aplikasi mungkin memisahkan layar dengan aplikasi lain. Dalam mode jendela desktop atau di ChromeOS, aplikasi mungkin berada di jendela yang dapat diubah ukurannya. Bahkan mungkin ada lebih dari satu layar fisik, seperti pada perangkat foldable. Di semua kasus ini, ukuran layar fisik tidak relevan dengan memutuskan cara menampilkan konten.
Sebagai gantinya, buat keputusan berdasarkan bagian layar sebenarnya yang dialokasikan ke aplikasi Anda yang dijelaskan oleh metrik jendela saat ini yang disediakan oleh library Jetpack WindowManager. Untuk contoh cara menggunakan WindowManager di aplikasi Compose, lihat contoh JetNews.
Dengan menjadikan tata letak Anda adaptif dengan ruang tampilan yang tersedia juga akan mengurangi jumlah penanganan khusus yang diperlukan untuk mendukung platform seperti ChromeOS dan faktor bentuk seperti tablet dan perangkat foldable.
Setelah menentukan metrik ruang yang tersedia untuk aplikasi Anda, konversikan ukuran mentah menjadi class ukuran jendela seperti yang dijelaskan dalam Menggunakan class ukuran jendela. Class ukuran jendela adalah titik henti sementara yang didesain untuk menyeimbangkan kesederhanaan logika aplikasi dengan fleksibilitas agar aplikasi Anda dapat dioptimalkan untuk sebagian besar ukuran tampilan.
Class ukuran jendela mengacu pada keseluruhan jendela aplikasi Anda, jadi gunakan class ini untuk keputusan tata letak yang memengaruhi tata letak aplikasi secara keseluruhan. Anda dapat meneruskan class ukuran jendela ke bawah sebagai status, atau Anda dapat menjalankan logika tambahan untuk membuat status turunan guna diteruskan ke composable bertingkat.
@Composable fun MyApp( windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo(supportLargeAndXLargeWidth = true).windowSizeClass ) { // Decide whether to show the top app bar based on window size class. val showTopAppBar = windowSizeClass.isHeightAtLeastBreakpoint(WindowSizeClass.HEIGHT_DP_MEDIUM_LOWER_BOUND) // MyScreen logic is based on the showTopAppBar boolean flag. MyScreen( showTopAppBar = showTopAppBar, /* ... */ ) }
Pendekatan berlapis membatasi logika ukuran tampilan ke satu lokasi, bukan menyebarkannya di aplikasi Anda di banyak tempat yang harus terus disinkronkan. Satu lokasi menghasilkan status, yang dapat secara eksplisit diteruskan ke composable lain seperti status aplikasi lainnya. Meneruskan status secara eksplisit menyederhanakan composable individual karena composable menggunakan class ukuran jendela atau konfigurasi yang ditentukan bersama data lainnya.
Composable bertingkat yang fleksibel dapat digunakan kembali
Composable lebih dapat digunakan kembali saat dapat ditempatkan di berbagai tempat. Jika composable harus ditempatkan di lokasi tertentu dengan ukuran tertentu, composable tersebut kemungkinan tidak dapat digunakan kembali dalam konteks lain. Ini juga berarti bahwa composable individual yang dapat digunakan kembali harus menghindari ketergantungan pada informasi ukuran tampilan global secara implisit.
Bayangkan composable bertingkat yang mengimplementasikan tata letak detail daftar yang mungkin menampilkan satu atau dua panel secara berdampingan:
Keputusan detail daftar harus menjadi bagian dari tata letak keseluruhan untuk aplikasi, sehingga keputusan diteruskan dari composable tingkat konten:
@Composable fun AdaptivePane( showOnePane: Boolean, /* ... */ ) { if (showOnePane) { OnePane(/* ... */) } else { TwoPane(/* ... */) } }
Bagaimana jika Anda menginginkan composable dapat mengubah tata letaknya secara independen berdasarkan ruang tampilan yang tersedia, misalnya, kartu yang menampilkan detail tambahan jika ruangnya memungkinkan? Anda ingin menjalankan beberapa logika berdasarkan ukuran tampilan yang tersedia, tetapi ukuran mana yang spesifik?
Hindari mencoba menggunakan ukuran layar perangkat yang sebenarnya. Hal ini tidak akan akurat untuk berbagai jenis layar dan juga tidak akan akurat jika aplikasi tidak dalam layar penuh.
Karena composable ini bukan composable tingkat konten, jangan gunakan metrik jendela saat ini secara langsung.
Jika komponen ditempatkan dengan padding (seperti dengan inset), atau jika aplikasi menyertakan komponen seperti kolom samping navigasi atau panel aplikasi, jumlah ruang tampilan yang tersedia untuk composable mungkin berbeda secara signifikan dari keseluruhan ruang yang tersedia untuk aplikasi.
Gunakan lebar yang benar-benar disediakan composable untuk merendernya sendiri. Anda memiliki dua opsi untuk mendapatkan lebar tersebut:
Jika Anda ingin mengubah lokasi atau cara konten apa pun akan ditampilkan, gunakan koleksi pengubah atau tata letak khusus agar tata letaknya responsif. Ini dapat semudah memiliki turunan yang mengisi semua ruang yang tersedia, atau menata letak turunan dengan beberapa kolom jika ada cukup ruang.
Jika ingin mengubah item yang ditampilkan, Anda dapat menggunakan
BoxWithConstraintssebagai alternatif yang lebih efektif.BoxWithConstraintsmemberikan batasan pengukuran yang dapat Anda gunakan untuk memanggil berbagai composable berdasarkan ruang tampilan yang tersedia. Namun, hal ini memiliki konsekuensi, karenaBoxWithConstraintsmenangguhkan komposisi hingga fase tata letak, saat batasan ini diketahui, sehingga menyebabkan lebih banyak pekerjaan yang harus dilakukan selama tata letak.
@Composable fun Card(/* ... */) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(/* ... */) Title(/* ... */) } } else { Row { Column { Title(/* ... */) Description(/* ... */) } Image(/* ... */) } } } }
Membuat semua data tersedia untuk berbagai ukuran tampilan
Saat mengimplementasikan composable yang memanfaatkan ruang tampilan tambahan, Anda mungkin ingin menjadi efisien dan memuat data sebagai efek samping ukuran tampilan saat ini.
Namun, hal ini bertentangan dengan prinsip aliran data searah, dengan data dapat diangkat dan diberikan ke composable untuk dirender dengan tepat. Data yang cukup harus diberikan ke composable agar composable selalu memiliki konten yang cukup untuk ukuran tampilan apa pun, meskipun beberapa bagian konten mungkin tidak selalu digunakan.
@Composable fun Card( imageUrl: String, title: String, description: String ) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description(description) } Image(imageUrl) } } } }
Dengan menggunakan contoh Card, perhatikan bahwa description selalu diteruskan ke Card. Meskipun description hanya digunakan saat lebar mengizinkan untuk menampilkannya, Card selalu memerlukan description, terlepas dari lebar yang tersedia.
Selalu meneruskan konten yang cukup akan menyederhanakan tata letak adaptif dengan membuatnya kurang stateful dan menghindari pemicu efek samping saat beralih antar-ukuran tampilan (yang dapat terjadi karena perubahan ukuran jendela, perubahan orientasi, atau lipatan dan lipatan perangkat).
Prinsip ini juga memungkinkan untuk mempertahankan status di seluruh perubahan tata letak. Dengan mengangkat informasi yang mungkin tidak digunakan di semua ukuran tampilan, Anda dapat mempertahankan status aplikasi saat ukuran tata letak berubah.
Misalnya, Anda dapat mengangkat flag boolean showMore sehingga status aplikasi dipertahankan saat perubahan ukuran tampilan menyebabkan tata letak beralih antara menyembunyikan dan menampilkan konten:
@Composable fun Card( imageUrl: String, title: String, description: String ) { var showMore by remember { mutableStateOf(false) } BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(imageUrl) Title(title) } } else { Row { Column { Title(title) Description( description = description, showMore = showMore, onShowMoreToggled = { newValue -> showMore = newValue } ) } Image(imageUrl) } } } }
Pelajari lebih lanjut
Untuk mempelajari tata letak adaptif di Compose lebih lanjut, lihat referensi berikut:
Aplikasi contoh
- CanonicalLayouts adalah repositori pola desain terbukti yang memberikan pengalaman pengguna yang optimal pada tampilan besar.
- JetNews menunjukkan cara mendesain aplikasi yang menyesuaikan UI-nya untuk memanfaatkan ruang tampilan yang tersedia.
- Reply adalah contoh adaptif untuk mendukung perangkat seluler, tablet, dan perangkat foldable.
- Now in Android adalah aplikasi yang menggunakan tata letak adaptif untuk mendukung berbagai ukuran tampilan.
Video