Compose'da akış düzenleri

FlowRow ve FlowColumn, Row ve Column'ye benzeyen ancak kapsayıcıda yer kalmadığında öğelerin bir sonraki satıra akması bakımından farklılık gösteren composable'lardır. Bu işlem, birden fazla satır veya sütun oluşturur. Bir satırdaki öğe sayısı, maxItemsInEachRow veya maxItemsInEachColumn ayarlanarak da kontrol edilebilir. Duyarlı düzenler oluşturmak için genellikle FlowRow ve FlowColumn özelliklerini kullanabilirsiniz. Öğeler bir boyut için çok büyükse içerik kesilmez. maxItemsInEach* ile Modifier.weight(weight) özelliklerini birlikte kullanmak, gerektiğinde bir satırın veya sütunun genişliğini dolduran/genişleten düzenler oluşturmanıza yardımcı olabilir.

Tipik örnek, bir çip veya filtreleme kullanıcı arayüzü içindir:

Bir FlowRow'da 5 çip. Daha fazla alan olmadığında taşan içerik bir sonraki satırda gösteriliyor.
1. şekil. FlowRow
örneği

Temel kullanım

FlowRow veya FlowColumn kullanmak için bu composable'ları oluşturun ve standart akışı izlemesi gereken öğeleri içine yerleştirin:

@Composable
private fun FlowRowSimpleUsageExample() {
    FlowRow(modifier = Modifier.padding(8.dp)) {
        ChipItem("Price: High to Low")
        ChipItem("Avg rating: 4+")
        ChipItem("Free breakfast")
        ChipItem("Free cancellation")
        ChipItem("£50 pn")
    }
}

Bu snippet, yukarıda gösterilen kullanıcı arayüzüyle sonuçlanır. İlk satırda yer kalmadığında öğeler otomatik olarak bir sonraki satıra akar.

Akış düzeninin özellikleri

Akış düzenlerinde, uygulamanızda farklı düzenler oluşturmak için kullanabileceğiniz aşağıdaki özellikler ve mülkler bulunur.

Ana eksen düzeni: yatay veya dikey düzen

Ana eksen, öğelerin yerleştirildiği eksendir (örneğin, FlowRow içinde öğeler yatay olarak düzenlenir). FlowRow içindeki horizontalArrangement parametresi, boş alanın öğeler arasında dağıtılma şeklini kontrol eder.

Aşağıdaki tabloda, FlowRow için öğelerde horizontalArrangement ayarlanmasına ilişkin örnekler gösterilmektedir:

Yatay düzenleme FlowRow olarak ayarlandı

Sonuç

Arrangement.Start (Default)

Başlangıçla düzenlenen öğeler

Arrangement.SpaceBetween

Öğelerin aralarında boşluk olacak şekilde düzenlenmesi

Arrangement.Center

Ortaya yerleştirilmiş öğeler

Arrangement.End

Sona yerleştirilmiş öğeler

Arrangement.SpaceAround

Öğeler, etraflarında boşluk bırakılarak düzenlenir.

Arrangement.spacedBy(8.dp)

Belirli bir dp ile aralanmış öğeler

FlowColumn için verticalArrangement ile benzer seçenekler mevcuttur. Varsayılan değer Arrangement.Top'dir.

Çapraz eksen düzeni

Çapraz eksen, ana eksenin tersi yöndeki eksendir. Örneğin, FlowRow içinde bu, dikey eksendir. Kapsayıcının içindeki genel içeriklerin çapraz eksende düzenlenme şeklini değiştirmek için FlowRow için verticalArrangement, FlowColumn için horizontalArrangement kullanın.

FlowRow için aşağıdaki tabloda, öğelerde farklı verticalArrangement ayarlama örnekleri gösterilmektedir:

FlowRow cihazında dikey düzen ayarlandı

Sonuç

Arrangement.Top (Default)

Konteyner üstü düzenleme

Arrangement.Bottom

Kapsayıcı alt düzeni

Arrangement.Center

Kapsayıcı merkez düzenlemesi

FlowColumn için horizontalArrangement ile benzer seçenekler kullanılabilir. Varsayılan çapraz eksen düzeni Arrangement.Start'dır.

Bağımsız öğe hizalama

Satırdaki öğeleri farklı hizalamalarla yerleştirmek isteyebilirsiniz. Bu özellik, verticalArrangement ve horizontalArrangement özelliklerinden farklıdır. Çünkü öğeleri geçerli satırda hizalar. Bunu Modifier.align() ile uygulayabilirsiniz.

Örneğin, bir FlowRow içindeki öğeler farklı yüksekliklerde olduğunda satır, en büyük öğenin yüksekliğini alır ve Modifier.align(alignmentOption) öğelere uygular:

Dikey hizalama FlowRow olarak ayarlandı

Sonuç

Alignment.Top (Default)

Öğeler üst tarafa hizalandı

Alignment.Bottom

Öğeler alt tarafa hizalandı

Alignment.CenterVertically

Öğeler ortaya hizalanmış

FlowColumn için benzer seçenekler mevcuttur. Varsayılan hizalama Alignment.Start'dır.

Satır veya sütundaki maksimum öğe sayısı

maxItemsInEachRow veya maxItemsInEachColumn parametreleri, bir sonraki satıra kaydırılmadan önce bir satırda izin verilecek ana eksendeki maksimum öğe sayısını tanımlar. Varsayılan değer Int.MAX_INT'dır. Bu değer, boyutları satıra sığmalarına izin verdiği sürece mümkün olduğunca çok öğeye izin verir.

Örneğin, maxItemsInEachRow ayarlandığında ilk düzende yalnızca 3 öğe bulunur:

Maksimum değer ayarlanmadı

maxItemsInEachRow = 3

Akış satırında maksimum değer ayarlanmamış Akış satırında ayarlanan maksimum öğe sayısı

Öğe ağırlıkları

Ağırlık, bir öğeyi faktörüne ve yerleştirildiği satırdaki kullanılabilir alana göre büyütür. Önemli olarak, ağırlıkların bir öğenin genişliğini hesaplamak için kullanılma şekli açısından FlowRow ve Row arasında bir fark vardır. Rows için ağırlık, Row içindeki tüm öğelere göre belirlenir. FlowRow ile ağırlık, FlowRow kapsayıcısındaki tüm öğelere değil, bir öğenin yerleştirildiği satırdaki öğelere göre belirlenir.

Örneğin, hepsi bir çizgi üzerinde bulunan ve ağırlıkları 1f, 2f, 1f ve 3f olan 4 öğeniz varsa toplam ağırlık 7f olur. Bir satır veya sütundaki kalan alan 7f ile bölünür. Ardından, her öğenin genişliği weight * (remainingSpace / totalWeight) kullanılarak hesaplanır.

Izgara benzeri bir düzen oluşturmak için Modifier.weight ve FlowRow ile maksimum öğe ya da FlowColumn kombinasyonunu kullanabilirsiniz. Bu yaklaşım, cihazınızın boyutuna göre ayarlanan duyarlı düzenler oluşturmak için kullanışlıdır.

Ağırlıklar kullanarak elde edebileceğiniz sonuçlarla ilgili birkaç farklı örnek vardır. Aşağıda gösterildiği gibi, öğelerin eşit boyutlu olduğu bir ızgara örnek verilebilir:

Akış satırıyla oluşturulan ızgara
Şekil 2. FlowRow kullanarak ızgara oluşturma

Eşit öğe boyutlarından oluşan bir ızgara oluşturmak için aşağıdakileri yapabilirsiniz:

val rows = 3
val columns = 3
FlowRow(
    modifier = Modifier.padding(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp),
    maxItemsInEachRow = rows
) {
    val itemModifier = Modifier
        .padding(4.dp)
        .height(80.dp)
        .weight(1f)
        .clip(RoundedCornerShape(8.dp))
        .background(MaterialColors.Blue200)
    repeat(rows * columns) {
        Spacer(modifier = itemModifier)
    }
}

Önemli bir nokta: Başka bir öğe ekleyip 9 yerine 10 kez tekrarlarsanız son öğe, satırın toplam ağırlığı 1f olduğundan son sütunun tamamını kaplar:

Izgaradaki son öğe tam boyutta
3.şekil FlowRow kullanarak son öğenin tam genişliği kapladığı bir ızgara oluşturma

Ağırlıkları diğer Modifiers ile birleştirebilirsiniz. Örneğin, Modifier.width(exactDpAmount), Modifier.aspectRatio(aspectRatio) veya Modifier.fillMaxWidth(fraction). Bu değiştiricilerin tümü, FlowRow (veya FlowColumn) içindeki öğelerin duyarlı şekilde boyutlandırılmasına olanak tanımak için birlikte çalışır.

Ayrıca, farklı öğe boyutlarından oluşan alternatif bir ızgara da oluşturabilirsiniz. Bu ızgarada iki öğe genişliğin yarısını, bir öğe ise sonraki sütunun tam genişliğini kaplar:

Akış satırıyla alternatif ızgara
4.şekil FlowRow ile satırların boyutları değişiyor

Bu işlemi aşağıdaki kodla gerçekleştirebilirsiniz:

FlowRow(
    modifier = Modifier.padding(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp),
    maxItemsInEachRow = 2
) {
    val itemModifier = Modifier
        .padding(4.dp)
        .height(80.dp)
        .clip(RoundedCornerShape(8.dp))
        .background(Color.Blue)
    repeat(6) { item ->
        // if the item is the third item, don't use weight modifier, but rather fillMaxWidth
        if ((item + 1) % 3 == 0) {
            Spacer(modifier = itemModifier.fillMaxWidth())
        } else {
            Spacer(modifier = itemModifier.weight(0.5f))
        }
    }
}

Kesirli boyutlandırma

Modifier.fillMaxWidth(fraction) kullanarak bir öğenin kaplaması gereken kapsayıcının boyutunu belirtebilirsiniz. Bu, Modifier.fillMaxWidth(fraction) öğesinin Row veya Column için uygulandığında çalışma şeklinden farklıdır. Row/Column öğeleri, kapsayıcının tamamının genişliği yerine kalan genişliğin bir yüzdesini kullanır.

Örneğin, aşağıdaki kod FlowRow ve Row kullanıldığında farklı sonuçlar üretir:

FlowRow(
    modifier = Modifier.padding(4.dp),
    horizontalArrangement = Arrangement.spacedBy(4.dp),
    maxItemsInEachRow = 3
) {
    val itemModifier = Modifier
        .clip(RoundedCornerShape(8.dp))
    Box(
        modifier = itemModifier
            .height(200.dp)
            .width(60.dp)
            .background(Color.Red)
    )
    Box(
        modifier = itemModifier
            .height(200.dp)
            .fillMaxWidth(0.7f)
            .background(Color.Blue)
    )
    Box(
        modifier = itemModifier
            .height(200.dp)
            .weight(1f)
            .background(Color.Magenta)
    )
}

FlowRow: Tüm kapsayıcı genişliğinin 0,7'si kadar olan orta öğe.

Akış satırıyla kesirli genişlik

Row: Ortadaki öğe, kalan Row genişliğinin %0,7'sini kaplıyor.

Satırla birlikte kesirli genişlik

fillMaxColumnWidth() ve fillMaxRowHeight()

FlowColumn veya FlowRow içindeki bir öğeye Modifier.fillMaxColumnWidth() ya da Modifier.fillMaxRowHeight() uygulanması, aynı sütun veya satırdaki öğelerin sütun/satırdaki en büyük öğeyle aynı genişlik veya yüksekliğe sahip olmasını sağlar.

Örneğin, bu örnekte Android tatlılarının listesini göstermek için FlowColumn kullanılıyor. Öğelere Modifier.fillMaxColumnWidth() uygulandığında ve uygulanmadığında öğelerin genişlikleri arasındaki farkı ve öğelerin kaydırıldığını görebilirsiniz.

FlowColumn(
    Modifier
        .padding(20.dp)
        .fillMaxHeight()
        .fillMaxWidth(),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    verticalArrangement = Arrangement.spacedBy(8.dp),
    maxItemsInEachColumn = 5,
) {
    repeat(listDesserts.size) {
        Box(
            Modifier
                .fillMaxColumnWidth()
                .border(1.dp, Color.DarkGray, RoundedCornerShape(8.dp))
                .padding(8.dp)
        ) {

            Text(
                text = listDesserts[it],
                fontSize = 18.sp,
                modifier = Modifier.padding(3.dp)
            )
        }
    }
}

Her öğeye uygulanan Modifier.fillMaxColumnWidth()

fillMaxColumnWidth

Genişlik değişikliği ayarlanmamış (öğeleri sarmalama)

Maksimum sütun genişliği ayarlanmadı