Oluşturma düzeniyle ilgili temel bilgiler

Jetpack Compose, uygulamanızın kullanıcı arayüzünü tasarlamayı ve oluşturmayı çok daha kolay hale getirir. Compose, aşağıdaki yöntemlerle durumu kullanıcı arayüzü öğelerine dönüştürür:

  1. Öğelerin kompozisyonu
  2. Öğelerin düzeni
  3. Öğelerin çizimi

Dönüştürme durumunu kompozisyon, düzen ve çizim yoluyla kullanıcı arayüzüne aktarma

Bu belgede, Compose'un kullanıcı arayüzü öğelerinizi düzenlemenize yardımcı olmak için sunduğu bazı yapı taşları açıklanarak öğelerin düzenine odaklanılmıştır.

Oluşturma penceresindeki düzenlerin amaçları

Düzen sisteminin Jetpack Compose uygulamasının iki temel hedefi vardır:

Composable işlevlerin temelleri

Composable işlevler, Compose'un temel yapı taşıdır. Bir composable işlev, kullanıcı arayüzünüzün bir bölümünü açıklayan Unit yayan bir işlevdir. Bu işlev, giriş alır ve ekranda gösterilenleri oluşturur. Composable'lar hakkında daha fazla bilgi için Compose zihin modeli belgelerine göz atın.

Bir composable işlev, birkaç kullanıcı arayüzü öğesi yayınlayabilir. Ancak, nasıl düzenlenmeleri gerektiği konusunda yönlendirme sağlamazsanız Compose, öğeleri beğenmeyeceğiniz bir şekilde düzenleyebilir. Örneğin, bu kod iki metin öğesi oluşturur:

@Composable
fun ArtistCard() {
    Text("Alfred Sisley")
    Text("3 minutes ago")
}

Nasıl düzenlenmesini istediğiniz konusunda yönlendirme yapmadığınızda Oluştur, metin öğelerini üst üste yerleştirerek okunamaz hale getirir:

İki metin öğesi üst üste çizildiğinden metin okunmuyor

Compose, kullanıcı arayüzü öğelerinizi düzenlemenize yardımcı olmak için kullanıma hazır düzenlemeler sunar ve kendi daha özel düzenlerinizi tanımlamanızı kolaylaştırır.

Standart düzen bileşenleri

Çoğu durumda, yalnızca Compose'un standart düzen öğelerini kullanabilirsiniz.

Öğeleri ekrana dikey olarak yerleştirmek için Column kullanın.

@Composable
fun ArtistCardColumn() {
    Column {
        Text("Alfred Sisley")
        Text("3 minutes ago")
    }
}

Metnin okunabilir olması için sütun düzeninde yerleştirilmiş iki metin öğesi

Benzer şekilde, öğeleri ekrana yatay olarak yerleştirmek için Row kullanın. Hem Column hem de Row, içerdiği öğelerin hizalamasının yapılandırılmasını destekler.

@Composable
fun ArtistCardRow(artist: Artist) {
    Row(verticalAlignment = Alignment.CenterVertically) {
        Image(bitmap = artist.image, contentDescription = "Artist image")
        Column {
            Text(artist.name)
            Text(artist.lastSeenOnline)
        }
    }
}

Metin öğeleri sütununun yanında küçük bir grafik bulunan daha karmaşık bir düzen gösteriliyor.

Öğeleri birbirinin üzerine yerleştirmek için Box öğesini kullanın. Box, içerdiği öğelerin belirli bir hizalamasını yapılandırmayı da destekler.

@Composable
fun ArtistAvatar(artist: Artist) {
    Box {
        Image(bitmap = artist.image, contentDescription = "Artist image")
        Icon(Icons.Filled.Check, contentDescription = "Check mark")
    }
}

Üst üste yerleştirilmiş iki öğeyi gösterir.

Genellikle ihtiyacınız olan tek şey bu yapı taşlarıdır. Bu düzenleri uygulamanıza uygun daha ayrıntılı bir düzende birleştirmek için kendi composable işlevinizi yazabilirsiniz.

Üç basit düzen composable'ını (sütun, satır ve kutu) karşılaştırır.

Çocukların Row içindeki konumunu ayarlamak için horizontalArrangement ve verticalAlignment bağımsız değişkenlerini ayarlayın. Column için verticalArrangement ve horizontalAlignment bağımsız değişkenlerini ayarlayın:

@Composable
fun ArtistCardArrangement(artist: Artist) {
    Row(
        verticalAlignment = Alignment.CenterVertically,
        horizontalArrangement = Arrangement.End
    ) {
        Image(bitmap = artist.image, contentDescription = "Artist image")
        Column { /*...*/ }
    }
}

Öğeler sağa hizalanmış

Düzen modeli

Düzen modelinde, kullanıcı arayüzü ağacı tek bir geçişte düzenlenir. Her düğümden önce kendisini ölçmesi, ardından da tüm alt öğeleri yinelemeli olarak ölçmesi istenir. Bu işlem sırasında boyut kısıtlamaları ağaçta alt öğelere aktarılır. Ardından, yaprak düğümler boyutlandırılıp yerleştirilir. Çözülen boyutlar ve yerleştirme talimatları ağaçta yukarıya doğru iletilir.

Kısaca, ebeveynler çocuklarından önce ölçülür ancak çocuklarından sonra boyutlandırılır ve yerleştirilir.

Aşağıdaki SearchResult işlevini ele alalım.

@Composable
fun SearchResult() {
    Row {
        Image(
            // ...
        )
        Column {
            Text(
                // ...
            )
            Text(
                // ...
            )
        }
    }
}

Bu işlev aşağıdaki kullanıcı arayüzü ağacını oluşturur.

SearchResult
  Row
    Image
    Column
      Text
      Text

SearchResult örneğinde, kullanıcı arayüzü ağacı düzeni şu sırayı izler:

  1. Kök düğüm Row ölçülür.
  2. Kök düğüm Row, ilk alt öğesi olan Image'den ölçüm yapmasını ister.
  3. Image bir yaprak düğüm olduğundan (yani alt öğesi yoktur) boyut bildirir ve yerleştirme talimatlarını döndürür.
  4. Kök düğüm Row, ikinci alt öğesi Column'den ölçüm yapmasını ister.
  5. Column düğümü, ilk Text alt öğesinden ölçüm yapmasını ister.
  6. İlk Text düğümü bir yaprak düğüm olduğundan bir boyut bildirir ve yerleştirme talimatlarını döndürür.
  7. Column düğümü, ikinci Text alt öğesinden ölçüm yapmasını ister.
  8. İkinci Text düğümü bir yaprak düğüm olduğundan bir boyut bildirir ve yerleştirme talimatlarını döndürür.
  9. Column düğümü, alt öğelerini ölçüp boyutlandırıp yerleştirdikten sonra kendi boyutunu ve yerleşimini belirleyebilir.
  10. Kök düğüm Row, alt öğelerini ölçüp boyutlandırıp yerleştirdikten sonra kendi boyutunu ve yerleşimini belirleyebilir.

Arama sonucu kullanıcı arayüzü ağacında ölçme, boyutlandırma ve yerleştirme sırası

Performans

Compose, çocukları yalnızca bir kez ölçerek yüksek performans elde eder. Tek geçişli ölçüm, performansı artırır ve Compose'un derin kullanıcı arayüzü ağaçlarını verimli bir şekilde işlemesine olanak tanır. Bir öğe alt öğesini iki kez ölçtüyse ve bu alt öğe de kendi alt öğelerinin her birini iki kez ölçtüyse ve bu böyle devam ettiyse, tüm kullanıcı arayüzünü yerleştirmek için tek bir deneme çok fazla iş yapmak zorunda kalır ve bu da uygulamanızın performansını korumayı zorlaştırır.

Düzeninizin herhangi bir nedenle birden fazla ölçüye ihtiyacı varsa Compose, intrinsic ölçüler adı verilen özel bir sistem sunar. Bu özellik hakkında daha fazla bilgiyi Intrinsic measurements in Compose layouts (Compose düzenlerinde doğal ölçümler) başlıklı makalede bulabilirsiniz.

Ölçüm ve yerleşim, düzenleme adımının ayrı alt aşamaları olduğundan yalnızca öğelerin yerleşimini etkileyen, ölçümü etkilemeyen değişiklikler ayrı ayrı uygulanabilir.

Düzenlerinizde değiştiricileri kullanma

Compose değiştiricileri bölümünde açıklandığı gibi, composable'larınızı süslemek veya geliştirmek için değiştiricileri kullanabilirsiniz. Düzeninizi özelleştirmek için değiştiriciler gereklidir. Örneğin, burada ArtistCard simgesini özelleştirmek için birkaç değiştiriciyi zincirleme olarak kullanıyoruz:

@Composable
fun ArtistCardModifiers(
    artist: Artist,
    onClick: () -> Unit
) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        Row(verticalAlignment = Alignment.CenterVertically) { /*...*/ }
        Spacer(Modifier.size(padding))
        Card(
            elevation = CardDefaults.cardElevation(defaultElevation = 4.dp),
        ) { /*...*/ }
    }
}

Grafiklerin düzenlenme şeklini ve hangi alanların kullanıcı girişine yanıt vereceğini değiştirmek için değiştiricilerin kullanıldığı daha da karmaşık bir düzen

Yukarıdaki kodda, birlikte kullanılan farklı değiştirici işlevlere dikkat edin.

  • clickable, kullanıcı girişine karşı birleştirilebilir bir tepki verir ve dalgalanma gösterir.
  • padding, bir öğenin etrafına boşluk yerleştirir.
  • fillMaxWidth, composable'ın üst öğesinden kendisine verilen maksimum genişliği doldurmasını sağlar.
  • size(), bir öğenin tercih edilen genişliğini ve yüksekliğini belirtir.

Kaydırılabilir düzenler

Kaydırılabilir düzenler hakkında daha fazla bilgiyi Compose hareketleri dokümanında bulabilirsiniz.

Listeler ve tembel listeler için Compose listeleri belgelerine göz atın.

Duyarlı düzenler

Düzen, farklı ekran yönleri ve form faktörü boyutları dikkate alınarak tasarlanmalıdır. Compose, birleştirilebilir düzenlerinizi çeşitli ekran yapılandırmalarına uyarlamayı kolaylaştırmak için kullanıma hazır birkaç mekanizma sunar.

Kısıtlamalar

Üst öğeden gelen kısıtlamaları bilmek ve düzeni buna göre tasarlamak için BoxWithConstraints kullanabilirsiniz. Ölçüm kısıtlamaları içerik lambda'sının kapsamı içinde bulunabilir. Farklı ekran yapılandırmaları için farklı düzenler oluşturmak üzere bu ölçüm kısıtlamalarını kullanabilirsiniz:

@Composable
fun WithConstraintsComposable() {
    BoxWithConstraints {
        Text("My minHeight is $minHeight while my maxWidth is $maxWidth")
    }
}

Alan tabanlı düzenler

Compose, kullanıcı arayüzü oluşturmayı kolaylaştırmak için androidx.compose.material:material bağımlılığıyla (Android Studio'da Compose projesi oluştururken dahil edilir) Material Design'a dayalı çok çeşitli composable'lar sunar. Drawer, FloatingActionButton ve TopAppBar gibi öğelerin tümü sağlanır.

Material bileşenleri, Compose'un composable'ların üzerine bir özelleştirme katmanı getirmek için kullandığı bir kalıp olan yuva API'lerini yoğun bir şekilde kullanır. Bu yaklaşım, bileşenlerin daha esnek olmasını sağlar. Çünkü bu yaklaşımda, alt öğenin her yapılandırma parametresini kullanıma sunmak yerine kendisini yapılandırabilen bir alt öğe kabul edilir. Yuvalar, geliştiricinin istediği şekilde doldurabileceği boş bir alan bırakır. Örneğin, TopAppBar içinde özelleştirebileceğiniz yuvalar şunlardır:

Bir Material Components uygulama çubuğundaki kullanılabilir yuvaları gösteren şema

Composable'lar genellikle content composable lambda ( content: @Composable () -> Unit) alır. Slot API'leri, belirli kullanımlar için birden fazla content parametresi sunar. Örneğin, TopAppBar, title, navigationIcon ve actions için içerik sağlamanıza olanak tanır.

Örneğin, Scaffold temel Materyal Tasarım düzen yapısına sahip bir kullanıcı arayüzü uygulamanıza olanak tanır. Scaffold, TopAppBar, BottomAppBar, FloatingActionButton ve Drawer gibi en yaygın üst düzey Materyal bileşenleri için yuvalar sağlar. Scaffold kullanarak bu bileşenlerin doğru şekilde konumlandırıldığından ve birlikte düzgün çalıştığından kolayca emin olabilirsiniz.

Birden fazla öğeyi konumlandırmak için Scaffold'u kullanan JetNews örnek uygulaması

@Composable
fun HomeScreen(/*...*/) {
    ModalNavigationDrawer(drawerContent = { /* ... */ }) {
        Scaffold(
            topBar = { /*...*/ }
        ) { contentPadding ->
            // ...
        }
    }
}