Anda memerlukan berbagai jenis informasi, seperti kemampuan perangkat dan status aplikasi, untuk memperbarui tata letak aplikasi. Lebar dan tinggi jendela adalah informasi yang paling umum digunakan. Selain itu, Anda dapat merujuk ke informasi berikut:
- Posisi jendela
- Presisi perangkat penunjuk
- Jenis keyboard
- Apakah kamera dan mikrofon didukung oleh perangkat
- Jarak antara pengguna dan tampilan perangkat
Karena informasi diperbarui secara dinamis, Anda harus memantaunya dan memicu komposisi ulang saat ada pembaruan.
Fungsi mediaQuery mengabstraksi detail pengambilan informasi
dan memungkinkan Anda berfokus pada penentuan kondisi untuk memicu pembaruan tata letak.
Contoh berikut mengalihkan tata letak ke TabletopLayout saat posisi perangkat foldable adalah tabletop:
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
Mengaktifkan fungsi mediaQuery
Untuk mengaktifkan fungsi mediaQuery,
tetapkan atribut isMediaQueryIntegrationEnabled dari
objek ComposeUiFlags ke true:
class MyApplication : Application() { override fun onCreate() { ComposeUiFlags.isMediaQueryIntegrationEnabled = true super.onCreate() } }
Menentukan kondisi dengan parameter
Anda dapat menentukan kondisi sebagai lambda
yang dievaluasi dalam UiMediaScope.
Fungsi mediaQuery mengevaluasi kondisi sesuai dengan status saat ini dan kemampuan perangkat.
Fungsi ini menampilkan nilai boolean, sehingga Anda dapat menentukan tata letak dengan cabang kondisional seperti ekspresi if.
Tabel 1 menjelaskan parameter yang tersedia di UiMediaScope.
| Parameter | Jenis nilai | Deskripsi |
|---|---|---|
windowWidth |
Dp |
Lebar jendela saat ini dalam dp. |
windowHeight |
Dp |
Tinggi jendela saat ini dalam dp. |
windowPosture |
UiMediaScope.Posture |
Posisi jendela aplikasi saat ini. |
pointerPrecision |
UiMediaScope.PointerPrecision |
Presisi tertinggi dari perangkat penunjuk yang tersedia. |
keyboardKind |
UiMediaScope.KeyboardKind |
Jenis keyboard yang tersedia atau terhubung. |
hasCamera |
Boolean |
Apakah kamera didukung di perangkat. |
hasMicrophone |
Boolean |
Apakah mikrofon didukung di perangkat. |
viewingDistance |
UiMediaScope.ViewingDistance |
Jarak umum antara pengguna dan layar perangkat. |
Objek UiMediaScope menyelesaikan nilai parameter.
Fungsi mediaQuery menggunakan LocalUiMediaScope.current
untuk mengakses objek UiMediaScope,
yang mewakili kemampuan dan konteks perangkat saat ini.
Objek ini diperbarui secara dinamis saat ada perubahan, seperti saat pengguna mengubah posisi perangkat.
Fungsi mediaQuery kemudian mengevaluasi lambda query dengan objek UiMediaScope yang diperbarui dan menampilkan nilai boolean.
Misalnya, cuplikan berikut memilih antara TabletopLayout dan FlatLayout berdasarkan nilai parameter windowPosture.
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
Membuat keputusan berdasarkan ukuran jendela
Class ukuran jendela adalah sekumpulan titik henti sementara area pandang tidak berubah
yang membantu Anda mendesain, mengembangkan, dan menguji tata letak adaptif.
Anda dapat membandingkan dua parameter yang mewakili ukuran jendela saat ini dengan nilai minimum yang ditentukan dalam class ukuran jendela.
Contoh berikut mengubah jumlah panel sesuai dengan lebar jendela.
WindowSizeClass class memiliki konstanta untuk nilai minimum
class ukuran jendela (Gambar 1).
Fungsi derivedMediaQuery mengevaluasi lambda query
dan menggabungkan hasilnya dalam derivedStateOf.
Karena windowWidth dan windowHeight dapat sering diperbarui, panggil fungsi derivedMediaQuery, bukan fungsi mediaQuery saat Anda merujuk ke parameter tersebut dalam lambda query.
val narrowerThanMedium by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_MEDIUM_LOWER_BOUND.dp } val narrowerThanExpanded by derivedMediaQuery { windowWidth < WindowSizeClass.WIDTH_DP_EXPANDED_LOWER_BOUND.dp } when { narrowerThanMedium -> SinglePaneLayout() narrowerThanExpanded -> TwoPaneLayout() else -> ThreePaneLayout() }
Memperbarui tata letak sesuai dengan posisi jendela
Parameter windowPosture menjelaskan posisi jendela saat ini sebagai objek UiMediaScope.Posture.
Anda dapat memeriksa posisi saat ini dengan membandingkan parameter
dengan nilai yang ditentukan dalam class UiMediaScope.Posture.
Contoh berikut mengalihkan tata letak sesuai dengan posisi jendela:
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
Memeriksa presisi perangkat penunjuk yang tersedia
Perangkat penunjuk dengan presisi tinggi membantu pengguna menunjuk elemen UI dengan tepat. Presisi perangkat penunjuk bergantung pada jenis perangkat.
Parameter pointerPrecision menjelaskan presisi perangkat penunjuk yang tersedia, seperti mouse dan layar sentuh.
Ada empat nilai yang ditentukan dalam class UiMediaScope.PointerPrecision:
Fine, Coarse, Blunt, dan None.
None berarti tidak ada perangkat penunjuk yang tersedia.
Presisi berkisar dari tertinggi hingga terendah dalam urutan ini: Fine, Coarse, dan Blunt.
Jika beberapa perangkat penunjuk tersedia dan presisinya berbeda, parameter akan diselesaikan dengan presisi tertinggi.
Misalnya, jika ada dua perangkat penunjuk — perangkat presisi Fine dan perangkat presisi Blunt — Fine adalah nilai parameter pointerPrecision.
Contoh berikut menampilkan tombol yang lebih besar saat pengguna menggunakan perangkat penunjuk dengan presisi rendah:
if (mediaQuery { pointerPrecision == UiMediaScope.PointerPrecision.Blunt }) { LargeSizeButton() } else { NormalSizeButton() }
Memeriksa jenis keyboard yang tersedia
Parameter keyboardKind mewakili jenis keyboard yang tersedia:
Physical, Virtual, dan None.
Jika keyboard virtual ditampilkan dan keyboard hardware tersedia pada saat yang sama, parameter akan diselesaikan sebagai Physical.
Jika tidak ada yang terdeteksi, None adalah nilai parameter.
Contoh berikut menampilkan pesan yang menyarankan pengguna untuk menghubungkan keyboard jika tidak ada keyboard yang terdeteksi:
if (mediaQuery { keyboardKind == UiMediaScope.KeyboardKind.None }) { SuggestKeyboardConnect() }
Memeriksa apakah perangkat mendukung kamera dan mikrofon
Beberapa perangkat tidak mendukung kamera atau mikrofon.
Anda dapat memeriksa apakah perangkat mendukung kamera dan mikrofon dengan parameter hasCamera dan parameter hasMicrophone.
Contoh berikut menampilkan tombol untuk digunakan dengan kamera dan mikrofon saat perangkat mendukungnya:
Row { OutlinedTextField(state = rememberTextFieldState()) // Show the MicButton when the device supports a microphone. if (mediaQuery { hasMicrophone }) { MicButton() } // Show the CameraButton when the device supports a camera. if (mediaQuery { hasCamera }) { CameraButton() } }
Menyesuaikan UI dengan perkiraan jarak pandang
Jarak pandang adalah faktor yang membantu menentukan tata letak.
Jika pengguna menggunakan aplikasi dari jarak jauh, mereka akan mengharapkan teks dan elemen UI menjadi lebih besar.
Parameter viewingDistance memberikan perkiraan jarak pandang berdasarkan jenis perangkat dan konteks penggunaan umumnya.
Ada tiga nilai yang ditentukan dalam class UiMediaScope.ViewingDistance:
Near, Medium, dan Far.
Near berarti layar berada dalam jarak dekat, dan Far berarti perangkat dilihat dari jarak jauh.
Contoh berikut meningkatkan ukuran font saat jarak pandang adalah Far atau Medium:
val fontSize = when { mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Far } -> 20.sp mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Medium } -> 18.sp else -> 16.sp }
Melihat pratinjau komponen UI
Anda dapat memanggil fungsi mediaQuery dan derivedMediaQuery dalam fungsi composable untuk melihat pratinjau komponen UI.
Cuplikan berikut memilih antara TabletopLayout dan FlatLayout berdasarkan nilai parameter windowPosture.
Untuk melihat pratinjau TabletopLayout, parameter windowPosture harus berupa
UiMediaScope.Posture.Tabletop.
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
Fungsi mediaQuery dan derivedMediaQuery mengevaluasi
lambda query yang diberikan dalam objek UiMediaScope,
yang disediakan sebagai LocalUiMediaScope.current.
Anda dapat menggantinya dengan langkah-langkah berikut:
- Mengaktifkan fungsi
mediaQuery. - Menentukan objek kustom yang mengimplementasikan antarmuka
UiMediaScope. - Menetapkan objek kustom ke
LocalUiMediaScopedengan fungsiCompositionLocalProvider. - Memanggil composable untuk melihat pratinjau dalam lambda konten fungsi
CompositionLocalProvider.
Anda dapat melihat pratinjau TabletopLayout dengan contoh berikut:
@Preview @Composable fun PreviewLayoutForTabletop() { // Step 1: Enable the mediaQuery function ComposeUiFlags.isMediaQueryIntegrationEnabled = true val currentUiMediaScope = LocalUiMediaScope.current // Step 2: Define a custom object implementing the UiMediaScope interface. // The object overrides the windowPosture parameter. // The resolution of the remaining parameters is deferred to the currentUiMediaScope object. val uiMediaScope = remember(currentUiMediaScope) { object : UiMediaScope by currentUiMediaScope { override val windowPosture: UiMediaScope.Posture = UiMediaScope.Posture.Tabletop } } // Step 3: Set the object to the LocalUiMediaScope. CompositionLocalProvider(LocalUiMediaScope provides uiMediaScope) { // Step 4: Call the composable to preview. when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() } } }