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 melihat informasi berikut:
- Posisi jendela
- Presisi perangkat penunjuk
- Jenis keyboard
- Apakah kamera dan mikrofon didukung oleh perangkat
- Jarak antara pengguna dan layar perangkat
Karena informasi diperbarui secara dinamis, Anda perlu memantaunya dan memicu rekomposisi saat ada pembaruan.
Fungsi mediaQuery mengabstraksi detail pengambilan informasi
dan memungkinkan Anda berfokus pada penentuan kondisi untuk memicu update tata letak.
Contoh berikut mengalihkan tata letak ke TabletopLayout
saat postur perangkat foldable adalah tabletop:
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
Aktifkan 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 berdasarkan
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 postur 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 merepresentasikan ukuran jendela saat ini dengan nilai minimum yang ditentukan dalam class ukuran jendela.
Contoh berikut mengubah jumlah panel sesuai dengan lebar jendela.
Class WindowSizeClass memiliki konstanta untuk nilai minimum
class ukuran jendela (Gambar 1).
Fungsi derivedMediaQuery mengevaluasi lambda query
dan membungkus 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 postur jendela
Parameter windowPosture menjelaskan postur jendela saat ini
sebagai objek UiMediaScope.Posture.
Anda dapat memeriksa postur saat ini dengan membandingkan parameter
dengan nilai yang ditentukan dalam class UiMediaScope.Posture.
Contoh berikut mengganti tata letak sesuai dengan postur 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 presisi tinggi membantu pengguna menunjuk elemen UI secara presisi. 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 diselesaikan dengan presisi tertinggi.
Misalnya, jika ada dua perangkat penunjuk — perangkat presisi Fine dan perangkat presisi Blunt —
Fine adalah nilai parameter pointerPrecision.
Contoh berikut menunjukkan 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 diselesaikan sebagai Physical.
Jika keduanya tidak 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 menunjukkan tombol yang akan 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 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 memperbesar 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:
- Aktifkan fungsi
mediaQuery. - Tentukan objek kustom yang mengimplementasikan antarmuka
UiMediaScope. - Tetapkan objek kustom ke
LocalUiMediaScopedengan fungsiCompositionLocalProvider. - Panggil composable untuk melihat pratinjau di 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() } } }