Uygulamanızın kullanıcı arayüzü, farklı ekran boyutlarını, yönlerini ve form faktörlerini hesaba katmalıdır. Uyarlanabilir düzen, kullanılabilir ekran alanına göre değişir. Bu değişiklikler, basit düzen düzenlemelerinden yer doldurmaya ve ek alandan yararlanmak için düzenleri tamamen değiştirmeye kadar değişiklik gösterir.
Bildirim temelli kullanıcı arayüzü araç seti Jetpack Compose, içeriği çeşitli boyutlarda farklı şekilde oluşturacak şekilde ayarlayan düzenler tasarlama ve uygulamaya uygundur. Bu dokümanda, kullanıcı arayüzünüzü duyarlı hale getirmek için Yazma özelliğini nasıl kullanabileceğinize dair bazı yönergeler açıklanmaktadır.
Ekran düzeyindeki öğeler için büyük düzen değişiklikleri yapın
Bir uygulamanın tamamını ortaya koymak için E-posta Yaz'ı kullanırken uygulama düzeyinde ve ekran düzeyinde kombinasyonlar, uygulamanızın oluşturması için ayrılan tüm alanı kaplar. Tasarımınızda bu düzeyde, büyük ekranlardan yararlanmak için bir ekranın genel düzenini değiştirmek mantıklı olabilir.
Düzen kararlarını vermek için fiziksel donanım değerlerini kullanmaktan kaçının. Sabit bir somut değere göre karar vermek cazip gelebilir (Cihaz bir tablet mi? Fiziksel ekranın belirli bir en boy oranı var mı?) ancak bu sorulara verilen yanıtlar kullanıcı arayüzünüzün çalışabileceği alanı belirlemek için yararlı olmayabilir.
Tabletlerde bir uygulama, çoklu pencere modunda çalışıyor olabilir. Bu durumda, uygulama ekranı başka bir uygulamayla bölebilir. ChromeOS'te ise bir uygulama yeniden boyutlandırılabilir bir pencerede olabilir. Katlanabilir cihazlar gibi birden fazla fiziksel ekran bile olabilir. Her durumda, içeriğin nasıl görüntüleneceğine karar verirken fiziksel ekran boyutu önemli değildir.
Bunun yerine, ekranın uygulamanıza ayrılmış gerçek kısmını (ör. Jetpack WindowManager kitaplığı tarafından sağlanan geçerli pencere metrikleri) temel alarak kararlar almanız gerekir. Bir oluşturma uygulamasında WindowManager'ın nasıl kullanılacağını görmek için JetNews örneğine göz atın.
Bu yaklaşımın uygulanması, yukarıdaki senaryoların tamamında iyi performans gösterdiğinden uygulamanızı daha esnek hale getirir. Düzenlerinizi ekran alanına uyumlu hale getirmek, ChromeOS gibi platformları ve tabletler ile katlanabilir cihazlar gibi form faktörlerini desteklemek için gereken özel kullanım miktarını da azaltır.
Uygulamanız için kullanılabilir olan alakalı alanı gözlemledikten sonra, ham boyutu Pencere Boyutu Sınıfları'nda açıklandığı gibi anlamlı bir boyut sınıfına dönüştürmeniz faydalı olacaktır. Bu şekilde boyutları, uygulamanızı birçok benzersiz durum için optimize etme esnekliğiyle sadeliği dengelemek üzere tasarlanmış ayrılma noktaları olan standart boyutlu paketler halinde gruplandırabilirsiniz. Bu boyut sınıfları, uygulamanızın genel aralığını ifade eder. Bu nedenle, genel ekran düzeninizi etkileyen düzen kararları için bu sınıfları kullanın. Bu boyut sınıflarını durum olarak aktarabilir veya iç içe yerleştirilmiş bileşiklere aktarmak için türetilmiş durum oluşturmak için ek mantık yürütebilirsiniz.
class MainActivity : ComponentActivity() { @OptIn(ExperimentalMaterial3WindowSizeClassApi::class) override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContent { val windowSizeClass = calculateWindowSizeClass(this) MyApp(windowSizeClass) } } } @Composable fun MyApp(windowSizeClass: WindowSizeClass) { // Perform logic on the size class to decide whether to show // the top app bar. val showTopAppBar = windowSizeClass.heightSizeClass != WindowHeightSizeClass.Compact // MyScreen knows nothing about window sizes, and performs logic // based on a Boolean flag. MyScreen( showTopAppBar = showTopAppBar, /* ... */ ) }
Bu katmanlı yaklaşım, ekran boyutu mantığını tek bir konumla sınırlandırır. Böylece tek bir konumdan dağıtılarak uygulamanın senkronize kalması gereken birçok yere yayılmış olur. Bu tek konum, durumu oluşturur. Bu durum, diğer uygulama durumlarında olduğu gibi açıkça diğer bestelere aktarılabilir. Durumu açıkça iletmek, diğer verilerle birlikte boyut sınıfını veya belirtilen yapılandırmayı alan normal ve uyumlu işlevler oldukları için her bir besteyi basitleştirir.
Esnek iç içe yerleştirilmiş yeniden kullanılabilirler
Besteler, çok çeşitli yerlere yerleştirildiklerinde daha fazla kullanılabilir. Bir öğe her zaman belirli bir boyuta sahip belirli bir konuma yerleştirileceğini varsayarsa bunu farklı bir konumda veya farklı miktarda kullanılabilir alanla yeniden kullanmak daha zor olur. Bu aynı zamanda, yeniden kullanılabilir tek tek bileşenlerin "global" boyut bilgilerine dayalı olarak dolaylı şekilde kaçınmaları gerektiği anlamına gelir.
Bir örneğe göz atalım: Liste ayrıntısı düzenini uygulayan iç içe yerleştirilmiş bir beste düşünün. Bu bölme, bir veya iki bölmeyi yan yana gösterebilir.
Tipik bir liste/ayrıntı düzeninin gösterildiği uygulama ekran görüntüsü. 1 liste alanıdır, 2 ayrıntı alanıdır.
Bu kararın, uygulamanın genel düzeninin bir parçası olmasını istiyoruz. Bu nedenle, kararı, yukarıda gördüğümüz gibi ekran düzeyinde bir kombinasyondan devre dışı bırakıyoruz:
@Composable fun AdaptivePane( showOnePane: Boolean, /* ... */ ) { if (showOnePane) { OnePane(/* ... */) } else { TwoPane(/* ... */) } }
Bunun yerine, kullanılabilir bir alan adına göre bir bağımsız öğenin düzenini bağımsız olarak değiştirmek istiyorsak ne olur? Örneğin, izin veriyorsa ek ayrıntılar göstermek isteyen bir kart ekleyebilirsiniz. Mevcut boyutlara göre birtakım mantık uygulamak istiyoruz ancak spesifik olarak hangi boyutu kullanmak istiyorsunuz?
Yukarıda gördüğümüz gibi, cihazın gerçek ekranının boyutunu kullanmayı denemekten kaçınmamız gerekir. Bu, birden fazla ekran için doğru olmaz ve ayrıca, uygulama tam ekran değilse doğru olmaz.
Beste, ekran düzeyinde bir bileşim olmadığından, yeniden kullanılabilirliği en üst düzeye çıkarmak için mevcut pencere metriklerini doğrudan kullanmamalıyız. Bileşen dolgu ile yerleştirildiyse (ör. kulaklıklar için) veya gezinme rayları ya da uygulama çubukları gibi bileşenler içeriyorsa bu öğelerde kullanılabilen alan miktarı, uygulamanın kullanılabilecek toplam alanından önemli ölçüde farklı olabilir.
Bu nedenle, kendisinin oluşturması için bestenin verildiği genişliği kullanmamız gerekir. Bu genişliği elde etmek için iki seçeneğimiz vardır:
İçeriğin gösterildiği veya nasıl görüntülendiğini değiştirmek istiyorsanız düzeni duyarlı hale getirmek için değiştiriciler koleksiyonunu veya özel düzeni kullanabilirsiniz. Bu, bir çocuğun mevcut tüm alanı doldurması veya yeterli alan varsa çocukların birden çok sütun koyması kadar basit olabilir.
Gösterdiğiniz şeyi değiştirmek istiyorsanız BoxWithConstraints
özelliğini daha güçlü bir alternatif olarak kullanabilirsiniz. Bu kullanılabilir öğe, mevcut alana göre farklı besteleri çağırmak için kullanabileceğiniz ölçüm kısıtlamaları sağlar. Bununla birlikte, BoxWithConstraints
besteyi Layout aşamasına kadar ertelediği için bu konfigürasyonlar zaman alır ve bu da düzen sırasında daha fazla iş yapılmasını sağlar.
@Composable fun Card(/* ... */) { BoxWithConstraints { if (maxWidth < 400.dp) { Column { Image(/* ... */) Title(/* ... */) } } else { Row { Column { Title(/* ... */) Description(/* ... */) } Image(/* ... */) } } } }
Tüm verilerin farklı boyutlarda kullanılabildiğinden emin olun
Ek ekran alanından yararlanırken, büyük ekranda kullanıcıya küçük ekrandan daha fazla içerik göstermek için yeriniz olabilir. Bu davranışla bir kombinasyon uygulanırken verimli olmak ve verileri mevcut boyutun yan etkisi olarak yüklemek cazip gelebilir.
Ancak bu, verilerin kaldırılıp uygun şekilde oluşturulması için bestelere sağlanabileceği tek yönlü veri akışı ilkelerine aykırıdır. Besteye yeterli veri sağlanması gerekir. Böylece, verilerin bir kısmı her zaman kullanılamasa bile bestenin her zaman herhangi bir boyutta görüntülenmesi gerekir.
@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) } } } }
Card
örneğine göre description
parametresi her zaman Card
parametresine iletilir. description
özelliği yalnızca genişliğin gösterilmesine izin verdiğinde kullanılsa da Card
, kullanılabilir genişlik ne olursa olsun her zaman için bunu gerektirir.
Uyarlanabilir düzenler her zaman daha az durum bilgisine sahip olarak basitleştirilerek daha
Bu ilke, düzen değişikliklerinde durumun korunmasına da olanak tanır. Her boyutta kullanılamayabilecek bilgileri kaldırarak düzen boyutu değiştikçe kullanıcının durumunu koruyabiliriz. Örneğin, yeniden boyutlandırma düzeninin gizlenmesi ve gösterilmesi arasında geçiş yapmasına neden olduğunda kullanıcının durumu korunabilmesi için showMore
Boole işaretini kaldırabiliriz:
@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) } } } }
Daha fazla bilgi
Compose'daki özel düzenler hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynakları inceleyin.
Örnek uygulamalar
- Büyük ekran standart düzenleri, büyük ekranlı cihazlarda en iyi kullanıcı deneyimini sağlayan, başarısı kanıtlanmış tasarım kalıplarından oluşan bir depodur
- JetNews, mevcut alanı kullanmak için kullanıcı arayüzünü uyarlayan bir uygulamanın nasıl tasarlanacağını gösteriyor
- Yanıtlama mobil cihaz, tablet ve katlanabilir cihazları desteklemek için uyarlanabilir bir örnektir
- Şimdi Android'de, farklı ekran boyutlarını desteklemek için uyarlanabilir düzenleri kullanan bir uygulama