Uygulama düzeninizi güncellemek için cihaz kapasitesi ve uygulama durumu gibi çeşitli bilgilere ihtiyacınız vardır. Pencere genişliği ve yüksekliği en çok tercih edilen bilgilerdir. Buna ek olarak, aşağıdaki bilgilere de göz atabilirsiniz:
- Pencere duruşu
- İşaretleme cihazlarının hassasiyeti
- Klavye türü
- Kamera ve mikrofonun cihaz tarafından desteklenip desteklenmediği
- Kullanıcı ile cihaz ekranı arasındaki mesafe
Bilgiler dinamik olarak güncellendiği için bunları izlemeniz ve güncelleme olduğunda yeniden oluşturmayı tetiklemeniz gerekir.
mediaQuery işlevi, bilgiyi getirme işleminin ayrıntılarını soyutlar ve düzen güncellemelerini tetikleyecek koşulu tanımlamaya odaklanmanızı sağlar.
Aşağıdaki örnekte, katlanabilir cihazın duruşu masaüstü olduğunda düzen TabletopLayout olarak değiştirilir:
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
mediaQuery işlevini etkinleştirme
mediaQuery işlevini etkinleştirmek için ComposeUiFlags nesnesinin isMediaQueryIntegrationEnabled özelliğini true olarak ayarlayın:
class MyApplication : Application() { override fun onCreate() { ComposeUiFlags.isMediaQueryIntegrationEnabled = true super.onCreate() } }
Parametrelerle koşul tanımlama
Bir koşulu, UiMediaScope içinde değerlendirilen bir lambda olarak tanımlayabilirsiniz.
mediaQuery işlevi, koşulu mevcut duruma ve cihaz özelliklerine göre değerlendirir.
İşlev, boole değeri döndürür.
Bu sayede, if ifadesi gibi koşullu dallarla
düzeni belirleyebilirsiniz.
Tablo 1'de UiMediaScope içinde kullanılabilen parametreler açıklanmaktadır.
| Parametre | Değer türü | Açıklama |
|---|---|---|
windowWidth |
Dp |
dp cinsinden mevcut pencere genişliği. |
windowHeight |
Dp |
Mevcut pencere yüksekliği (dp cinsinden). |
windowPosture |
UiMediaScope.Posture |
Uygulama penceresinin mevcut duruşu. |
pointerPrecision |
UiMediaScope.PointerPrecision |
Mevcut işaretleme cihazları arasında en yüksek hassasiyete sahip olan. |
keyboardKind |
UiMediaScope.KeyboardKind |
Kullanılabilir veya bağlı klavyenin türü. |
hasCamera |
Boolean |
Cihazda kameranın desteklenip desteklenmediği. |
hasMicrophone |
Boolean |
Mikrofonun cihazda desteklenip desteklenmediği. |
viewingDistance |
UiMediaScope.ViewingDistance |
Kullanıcı ile cihaz ekranı arasındaki ortalama mesafe. |
UiMediaScope nesnesi, parametrelerin değerlerini çözer.
mediaQuery işlevi, mevcut cihaz özelliklerini ve bağlamını temsil eden UiMediaScope nesnesine erişmek için LocalUiMediaScope.current kullanır.
Bu nesne, herhangi bir değişiklik yapıldığında (ör. kullanıcı cihazın duruşunu değiştirdiğinde) dinamik olarak güncellenir.
Ardından mediaQuery işlevi, güncellenmiş UiMediaScope nesnesiyle query lambda'yı değerlendirir ve bir boole değeri döndürür.
Örneğin, aşağıdaki snippet windowPosture parametre değerine göre TabletopLayout ve FlatLayout arasında seçim yapar.
@Composable fun VideoPlayer( // ... ) { // ... if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) { TabletopLayout() } else { FlatLayout() } // ... }
Pencere boyutuna göre karar verme
Pencere boyutu sınıfları, uyarlanabilir düzenler tasarlamanıza, geliştirmenize ve test etmenize yardımcı olan bir dizi özel görüntü alanı kesme noktasıdır.
Mevcut pencere boyutunu temsil eden iki parametreyi, pencere boyutu sınıflarında tanımlanan eşikle karşılaştırabilirsiniz.
Aşağıdaki örnekte, pencere genişliğine göre bölme sayısı değiştirilmektedir.
WindowSizeClass sınıfında, pencere boyutu sınıflarının eşikleri için sabitler bulunur (Şekil 1).
derivedMediaQuery işlevi, query lambda'yı değerlendirir ve sonucu bir derivedStateOf içine sarmalar.
windowWidth ve windowHeight sık sık güncellenebileceğinden, query lambda'da bu parametrelere referans verirken mediaQuery işlevi yerine derivedMediaQuery işlevini çağırın.
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() }
Düzeni pencere duruşuna göre güncelleme
windowPosture parametresi, geçerli pencere duruşunu UiMediaScope.Posture nesnesi olarak tanımlar.
Parametreyi UiMediaScope.Posture sınıfında tanımlanan değerlerle karşılaştırarak mevcut duruşu kontrol edebilirsiniz.
Aşağıdaki örnekte, düzen pencere duruşuna göre değiştirilir:
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
Kullanılabilir işaretleme cihazının hassasiyetini kontrol etme
Yüksek hassasiyetli işaretleme cihazı, kullanıcıların kullanıcı arayüzü öğelerini hassas bir şekilde işaretlemesine yardımcı olur. İşaretleme cihazının hassasiyeti, cihaz türüne bağlıdır.
pointerPrecision parametresi, fare ve dokunmatik ekran gibi kullanılabilir işaretleme cihazlarının hassasiyetini tanımlar.
UiMediaScope.PointerPrecision sınıfında tanımlanmış dört değer vardır:
Fine, Coarse, Blunt ve None.
None, işaretleme cihazı olmadığını gösterir.
Hassasiyet, en yüksekten en düşüğe doğru şu şekilde sıralanır:
Fine, Coarse ve Blunt.
Birden fazla işaretleme cihazı varsa ve bunların hassasiyetleri farklıysa parametre en yüksek hassasiyete sahip cihazla çözümlenir.
Örneğin, iki işaretleme cihazı varsa (biri Fine hassasiyetinde, diğeri Blunt hassasiyetinde) pointerPrecision parametresinin değeri Fine olur.
Aşağıdaki örnekte, kullanıcı düşük hassasiyetli bir işaretleme cihazı kullanırken daha büyük bir düğme gösterilmektedir:
if (mediaQuery { pointerPrecision == UiMediaScope.PointerPrecision.Blunt }) { LargeSizeButton() } else { NormalSizeButton() }
Kullanılabilir klavye türünü kontrol etme
keyboardKind parametresi, kullanılabilir klavyelerin türünü temsil eder:
Physical, Virtual ve None.
Dokunmatik klavye gösteriliyorsa ve aynı anda donanım klavyesi kullanılabiliyorsa parametre Physical olarak çözümlenir.
İkisi de algılanmazsa parametrenin değeri None olur.
Aşağıdaki örnekte, klavye algılanmadığında kullanıcılara klavye bağlamalarını öneren bir mesaj gösterilmektedir:
if (mediaQuery { keyboardKind == UiMediaScope.KeyboardKind.None }) { SuggestKeyboardConnect() }
Cihazın kamera ve mikrofonu destekleyip desteklemediğini kontrol etme
Bazı cihazlar kamera veya mikrofonları desteklemez.
Cihazın kamera ve mikrofonu destekleyip desteklemediğini hasCamera parametresi ve hasMicrophone parametresiyle kontrol edebilirsiniz.
Aşağıdaki örnekte, cihaz desteklediğinde kamera ve mikrofonla kullanılacak düğmeler gösterilmektedir:
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() } }
Kullanıcı arayüzünü tahmini izleme mesafesine göre ayarlama
Görüntüleme mesafesi, düzeni belirlemeye yardımcı olan bir faktördür.
Kullanıcı uygulamayı uzaktan kullanıyorsa metin ve kullanıcı arayüzü öğelerinin daha büyük olmasını bekler.
viewingDistance parametresi, cihaz türüne ve tipik kullanım bağlamına göre izleme mesafesinin tahminini sağlar.
UiMediaScope.ViewingDistance sınıfında tanımlanmış üç değer vardır:
Near, Medium ve Far.
Near, ekranın yakın mesafede olduğu, Far ise cihazın uzaktan görüntülendiği anlamına gelir.
Aşağıdaki örnekte, görüntüleme mesafesi Far veya Medium olduğunda yazı tipi boyutu artırılmaktadır:
val fontSize = when { mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Far } -> 20.sp mediaQuery { viewingDistance == UiMediaScope.ViewingDistance.Medium } -> 18.sp else -> 16.sp }
Kullanıcı arayüzü bileşenini önizleme
Kullanıcı arayüzü bileşenlerini önizlemek için composable işlevlerde mediaQuery ve derivedMediaQuery işlevlerini çağırabilirsiniz.
Aşağıdaki snippet, windowPosture parametre değerine göre TabletopLayout ve FlatLayout arasında seçim yapar.
TabletopLayout önizlemesi için windowPosture parametresi UiMediaScope.Posture.Tabletop olmalıdır.
when { mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop } -> TabletopLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Book } -> BookLayout() mediaQuery { windowPosture == UiMediaScope.Posture.Flat } -> FlatLayout() }
mediaQuery ve derivedMediaQuery işlevleri, LocalUiMediaScope.current olarak sağlanan bir UiMediaScope nesnesi içindeki belirli query lambda'yı değerlendirir.
Aşağıdaki adımları uygulayarak bu ayarı geçersiz kılabilirsiniz:
mediaQueryişlevini etkinleştirin.UiMediaScopearayüzünü uygulayan özel bir nesne tanımlayın.CompositionLocalProviderişleviyle özel nesneyiLocalUiMediaScopeolarak ayarlayın.CompositionLocalProviderişlevinin içerik lambda'sında önizlemek için composable'ı çağırın.
TabletopLayout için aşağıdaki örneği inceleyebilirsiniz:
@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() } } }