Farklı ekran boyutlarını destekleme

Farklı ekran boyutlarını desteklemek, uygulamanıza en geniş cihaz çeşitliliğinden ve en fazla sayıda kullanıcıdan erişilmesini sağlar.

Mümkün olduğunca fazla ekran boyutunu (farklı cihaz ekranları veya çoklu pencere modundaki farklı uygulama pencereleri) desteklemek için uygulama düzenlerinizi duyarlı ve uyarlanabilir olacak şekilde tasarlayın. Duyarlı/uyarlanabilir düzenler, ekran boyutundan bağımsız olarak optimize edilmiş bir kullanıcı deneyimi sunar. Bu sayede uygulamanız telefonlar, tabletler, katlanabilir cihazlar, ChromeOS cihazlar, dikey ve yatay yönler ve bölünmüş ekran modu ile masaüstü pencereleri gibi yeniden boyutlandırılabilir ekran yapılandırmalarını barındırabilir.

Duyarlı/uyarlanabilir düzenler, mevcut ekran alanına göre değişir. Değişiklikler, alanı dolduran küçük düzen ayarlarından (duyarlı tasarım) uygulamanızın farklı ekran boyutlarına en iyi şekilde uyum sağlayabilmesi için bir düzenin tamamen başka bir düzenle değiştirilmesine (uyarlanabilir tasarım) kadar çeşitlilik gösterir.

Bildirime dayalı bir kullanıcı arayüzü araç seti olan Jetpack Compose, içeriği farklı ekran boyutlarında farklı şekilde oluşturmak için dinamik olarak değişen düzenler tasarlamak ve uygulamak için idealdir.

İçerik düzeyindeki bileşenler için büyük düzen değişikliklerini açıkça belirtme

Uygulama düzeyindeki ve içerik düzeyindeki birleştirilebilirler, uygulamanızın tüm ekran alanını kaplar. Bu tür birleştirilebilirler için büyük ekranlarda uygulamanızın genel düzenini değiştirmek yararlı olabilir.

Düzenleme kararları almak için fiziksel donanım değerleri kullanmaktan kaçının. Sabit ve somut bir değere (Cihaz tablet mi? Fiziksel ekranın belirli bir en boy oranı var mı?), ancak bu soruların yanıtları, kullanıcı arayüzünüzde kullanılabilecek alanı belirlemek için yararlı olmayabilir.

Şekil 1. Telefon, katlanabilir cihaz, tablet ve dizüstü bilgisayar form faktörleri

Tabletler üzerinde bir uygulama, çoklu pencere modunda çalışıyor olabilir. Bu durumda uygulama, ekranı başka bir uygulamayla bölüyor olabilir. Masaüstü pencere modunda veya ChromeOS'te bir uygulama, boyutu değiştirilebilir bir pencerede olabilir. Katlanabilir cihazlarda olduğu gibi birden fazla fiziksel ekran bile olabilir. Bu durumların hiçbirinde, fiziksel ekran boyutu içeriğin nasıl gösterileceğine karar vermek için alakalı değildir.

Bunun yerine, Jetpack WindowManager kitaplığı tarafından sağlanan mevcut pencere metrikleriyle açıklanan, uygulamanıza ayrılan ekranın gerçek bölümüne göre karar vermelisiniz. WindowManager'ın bir Compose uygulamasında nasıl kullanılacağına dair örnek için JetNews örneğine bakın.

Düzenlemelerinizi mevcut ekran alanına uyarlanabilir hale getirmek, ChromeOS gibi platformları ve tabletler ile katlanabilir cihazlar gibi form faktörlerini desteklemek için gereken özel işlem miktarını da azaltır.

Uygulamanız için kullanılabilen alanın metriklerini belirlediğinizde, ham boyutu Pencere boyutu sınıflarını kullanma bölümünde açıklandığı şekilde bir pencere boyutu sınıfına dönüştürün. Pencere boyutu sınıfları, uygulama mantığının basitliğini uygulamanızı çoğu ekran boyutu için optimize etme esnekliğiyle dengelemek üzere tasarlanmış kesme noktalarıdır. Pencere boyutu sınıfları, uygulamanızın genel penceresini ifade eder. Bu nedenle, genel uygulama düzeninizi etkileyen düzen kararları için sınıfları kullanın. Pencere boyutu sınıflarını durum olarak iletebilir veya iç içe yerleştirilmiş kompozisyonlara iletilecek türetilmiş durum oluşturmak için ek mantık yürütebilirsiniz.

@Composable
fun MyApp(
    windowSizeClass: WindowSizeClass = currentWindowAdaptiveInfo().windowSizeClass
) {
    // Perform logic on the size class to decide whether to show the top app bar.
    val showTopAppBar = windowSizeClass.windowHeightSizeClass != WindowHeightSizeClass.COMPACT

    // MyScreen knows nothing about window sizes, and performs logic based on a Boolean flag.
    MyScreen(
        showTopAppBar = showTopAppBar,
        /* ... */
    )
}

Katmanlı yaklaşım, görüntü boyutu mantığını uygulamanızda senkronize tutulması gereken birçok yere dağıtmak yerine tek bir konuma sınırlandırır. Tek bir konum, diğer tüm uygulama durumları gibi diğer bileşenlere açıkça aktarılabilen bir durum oluşturur. Durumu açıkça iletmek, diğer verilerle birlikte pencere boyutu sınıfını veya belirtilen yapılandırmayı aldığından tek tek birleştirilebilir öğeleri basitleştirir.

Esnek iç içe yerleştirilmiş kompozisyonlar yeniden kullanılabilir

Birleştirilebilirler, çeşitli yerlere yerleştirilebildiğinde daha fazla yeniden kullanılabilir. Bir bileşenin belirli bir boyuta sahip olarak belirli bir yere yerleştirilmesi gerekiyorsa bileşenin başka bağlamlarda yeniden kullanılabilmesi olası değildir. Bu aynı zamanda, tek tek yeniden kullanılabilir bileşenlerin küresel ekran boyutu bilgilerine dolaylı olarak bağlı olmaktan kaçınması gerektiği anlamına da gelir.

Tek bir bölmeyi veya yan yana iki bölmeyi gösterebilen bir liste-ayrıntı düzeni uygulayan iç içe yerleştirilmiş bir bileşen düşünün:

Yan yana iki bölmeyi gösteren bir uygulama.
Şekil 2. Tipik bir liste-ayrıntı düzenini gösteren uygulama: 1 liste alanı, 2 ise ayrıntı alanıdır.

Liste ayrıntısı kararı, uygulamanın genel düzeninin bir parçası olmalıdır. Bu nedenle, karar içerik düzeyinde bir bileşenden iletilir:

@Composable
fun AdaptivePane(
    showOnePane: Boolean,
    /* ... */
) {
    if (showOnePane) {
        OnePane(/* ... */)
    } else {
        TwoPane(/* ... */)
    }
}

Bunun yerine, bir bileşenin mevcut ekran alanına göre düzenini bağımsız olarak değiştirmesini istiyorsanız (ör. alan izin veriyorsa ek ayrıntılar gösteren bir kart) ne olur? Kullanılabilir bir ekran boyutuna göre bazı mantık işlemleri yapmak istiyorsunuz ancak hangi boyuta göre?

Şekil 3. Yalnızca simge ve başlığı gösteren dar bir kart ve simgeyi, başlığı ve kısa açıklamayı gösteren daha geniş bir kart.

Cihazın gerçek ekranının boyutunu kullanmaya çalışmaktan kaçının. Bu, farklı ekran türleri için ve uygulama tam ekran değilse doğru olmaz.

Kompozit, içerik düzeyinde bir kompozit olmadığından mevcut pencere metriklerini doğrudan kullanmayın. Bileşen, dolguyla (ör. iç içe yerleştirilmiş öğelerle) yerleştirilmişse veya uygulamada gezinme çubuğu ya da uygulama çubuğu gibi bileşenler varsa bileşenin kullanabileceği ekran alanı miktarı, uygulamanın kullanabileceği toplam alandan önemli ölçüde farklı olabilir.

Kompozit öğenin kendisini oluşturmak için verilen genişliği kullanın. Bu genişliği elde etmek için iki seçeneğiniz vardır:

  • İçeriğin nerede veya nasıl gösterildiğini değiştirmek istiyorsanız düzeni duyarlı hale getirmek için bir değiştirici koleksiyonu veya özel düzen kullanın. Bu, bir çocuğun mevcut alanı doldurması veya yeterli alan varsa çocukları birden fazla sütunda düzenlemek kadar basit olabilir.

  • Gösterdiğiniz içeriği değiştirmek istiyorsanız daha güçlü bir alternatif olarak BoxWithConstraints simgesini kullanın. BoxWithConstraints, mevcut ekran alanına göre farklı bileşenleri çağırmak için kullanabileceğiniz ölçüm kısıtlamaları sağlar. Ancak BoxWithConstraints, bu kısıtlamaların bilindiği düzen aşamasına kadar kompozisyonu ertelediğinden, düzen sırasında daha fazla çalışma yapılmasına neden olarak bazı maliyetlere neden olur.

@Composable
fun Card(/* ... */) {
    BoxWithConstraints {
        if (maxWidth < 400.dp) {
            Column {
                Image(/* ... */)
                Title(/* ... */)
            }
        } else {
            Row {
                Column {
                    Title(/* ... */)
                    Description(/* ... */)
                }
                Image(/* ... */)
            }
        }
    }
}

Tüm verilerin farklı ekran boyutlarında kullanılabildiğinden emin olun

Ek ekran alanından yararlanan bir bileşeni uygularken verimli olmak ve mevcut ekran boyutunun yan etkisi olarak veri yüklemek isteyebilirsiniz.

Ancak bu, verilerin uygun şekilde oluşturulması için toplanarak bileşenlere sağlanabileceği tek yönlü veri akışı ilkesine aykırıdır. İçeriğin bir kısmı her zaman kullanılmasa bile, birleştirilebilir öğeye her zaman herhangi bir ekran boyutu için yeterli içerik olacak şekilde yeterli veri sağlanmalıdır.

@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ğini temel alarak, description değerinin her zaman Card işlevine iletildiğini unutmayın. description yalnızca genişlik gösterilmesine izin verdiğinde kullanılsa da Card, mevcut genişlikten bağımsız olarak her zaman description'yi gerektirir.

Her zaman yeterli içerik göndermek, uyarlanabilir düzenleri daha az duruma bağlı hale getirerek basitleştirir ve ekran boyutları arasında geçiş yaparken yan etkilerin tetiklenmesini (pencere boyutunun değiştirilmesi, yön değişikliği veya cihazın katlanması ve açılması nedeniyle oluşabilir) önler.

Bu ilke, durum bilgilerinin düzen değişikliklerinde korunmasına da olanak tanır. Tüm ekran boyutlarında kullanılamayabilecek bilgileri kaldırarak, uygulama durumunu düzen boyutu değiştikçe koruyabilirsiniz. Örneğin, ekran boyutunun değiştirilmesi nedeniyle düzenin içeriği gizleme ve gösterme arasında geçiş yapması durumunda uygulama durumunun korunması için bir showMoreboolean işaretçisi gönderebilirsiniz:

@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

Oluşturma'daki uyarlanabilir düzenler hakkında daha fazla bilgi edinmek için aşağıdaki kaynaklara bakın:

Örnek uygulamalar

  • CanonicalLayouts, büyük ekranlarda optimum kullanıcı deneyimi sağlayan kanıtlanmış tasarım kalıplarının bulunduğu bir depodur.
  • JetNews, kullanıcı arayüzünü mevcut ekran alanından yararlanacak şekilde uyarlayan bir uygulamanın nasıl tasarlanacağını gösterir.
  • Yanıtla, mobil cihazları, tabletleri ve katlanabilir cihazları desteklemek için uyarlanabilir bir örnektir.
  • Artık Android'de, farklı ekran boyutlarını desteklemek için uyarlanabilir düzenler kullanan bir uygulamadır.

Videolar