Compose'da akış düzenleri

FlowRow ve FlowColumn Row ve Column benzeri, ancak öğeleri farklı olan composable'lardır Kapsayıcıda boş yer kalmadığında bir sonraki satıra geçer. Bu işlemle birden fazla satır veya sütun oluşturulur. Bir satırdaki öğe sayısı da kontrol edilebilir maxItemsInEachRow veya maxItemsInEachColumn ayarlayarak öğrenin. Bu amaçla sıklıkla Duyarlı düzenler oluşturmak için FlowRow ve FlowColumn (içerik kesilmeyecek) bir boyut için çok büyükse ve Modifier.weight(weight) ile maxItemsInEach*, şu özelliklere sahip düzenler oluşturmanıza yardımcı olabilir: gerektiğinde bir satırın veya sütunun genişliğini doldurur/genişletir.

Çip veya filtreleme kullanıcı arayüzü tipik bir örnektir:

FlowRow'da 5 çip, mevcut olmadığında sonraki satıra taşan alanı gösterir
daha fazla alan kullanılabilir.
Şekil 1. FlowRow
örneği

Temel kullanım

FlowRow veya FlowColumn kullanmak için bu composable'ları oluşturup öğeleri yerleştirin şunun içinde standart akışı izlemesi gerekir:

@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, ilk satırda yer kalmadığında öğelerin otomatik olarak bir sonraki satıra aktığı, yukarıda gösterilen kullanıcı arayüzünü oluşturur.

Akış düzeninin özellikleri

Akış düzenleri, uygulamanızda farklı düzenler oluşturmak için kullanabileceğiniz aşağıdaki özelliklere ve özelliklere sahiptir.

Ana eksen yerleşimi: yatay veya dikey düzenleme

Ana eksen, öğelerin yerleştirildiği eksendir (örneğin, FlowRow, öğ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 ayarlama örnekleri gösterilmektedir:

Yatay düzenleme FlowRow hücresinde ayarlandı

Sonuç

Arrangement.Start (Default)

Başlangıcı olan öğeler

Arrangement.SpaceBetween

Öğelerin aralarında boşluk bırakacak şekilde ayarlanması

Arrangement.Center

Ortada düzenlenen öğeler

Arrangement.End

Sonuna yerleştirilen öğeler

Arrangement.SpaceAround

Etrafında boşluk bırakılarak düzenlenmiş öğeler

Arrangement.spacedBy(8.dp)

Belirli bir dp değerine göre aralıklı öğeler

FlowColumn için, benzer seçenekler verticalArrangement ile mevcuttur. varsayılan değer Arrangement.Top.

Çapraz eksen düzenlemesi

Çapraz eksen, ana eksene ters yönde olan eksendir. Örneğin, Örneğin, FlowRow, bu dikey eksendir. Genel kapsayıcının içindeki içerikler çapraz eksende düzenlenir, FlowRow için verticalArrangement ve için horizontalArrangement FlowColumn.

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

Dikey düzenleme FlowRow tarihinde ayarlandı

Sonuç

Arrangement.Top (Default)

Kapsayıcı üst düzenlemesi

Arrangement.Bottom

Kapsayıcı alt düzenlemesi

Arrangement.Center

Konteyner merkezi düzenlemesi

FlowColumn için horizontalArrangement ile benzer seçenekler mevcut. Varsayılan çapraz eksen ayarlaması: Arrangement.Start.

Bağımsız öğe hizalaması

Bir satırdaki öğeleri farklı boyutlarla tek tek yerleştirmek isteyebilirsiniz yardımcı olmaktır. Bu, verticalArrangement ve geçerli satırdaki öğeleri hizaladığı için horizontalArrangement. Bunu Modifier.align() ile uygulayabilirsiniz.

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

Dikey hizalama FlowRow olarak ayarlandı

Sonuç

Alignment.Top (Default)

Üste hizalanan öğeler

Alignment.Bottom

Öğeler alta hizalandı

Alignment.CenterVertically

Öğeler ortaya hizalanır.

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

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

maxItemsInEachRow veya maxItemsInEachColumn parametreleri maksimum sonrakine kaydırmadan önce bir satıra izin vermek için ana eksendeki öğeleri tıklayın. Varsayılan değer Int.MAX_INT'tür. Bu değer, boyutları satıra sığmasına izin verdiği sürece mümkün olduğunca fazla öğeye izin verir.

Örneğin, bir maxItemsInEachRow ayarlandığında başlangıç düzeni yalnızca 3 öğesi var:

Maksimum değer ayarlanmadı

maxItemsInEachRow = 3

Akış satırında maksimum değer ayarlanmadı Akış satırında maksimum öğe ayarlandı

Akış öğelerini geç yükleme

ContextualFlowRow ve ContextualFlowColumn uzmandır içerikleri geç yüklemenize olanak tanıyan FlowRow ve FlowColumn sürümü her zaman mevcut. Ayrıca öğelerin konumu ile ilgili bilgiler de sağlar. (dizin, satır numarası ve kullanılabilir boyut) örneğin, öğenin ilk satırı. Bu, büyük veri kümeleri için ve bağlamsal bilgilere ihtiyacınız varsa yararlıdır. bir liste oluşturabilirsiniz.

maxLines parametresi, gösterilen satır sayısını sınırlar ve overflow parametresi, istenen öğe için taşma işlemi olduğunda özel bir expandIndicator veya collapseIndicator.

Örneğin, "+ (kalan öğe sayısı)" değerini göstermek için veya "Daha Az Göster" düğme:

val totalCount = 40
var maxLines by remember {
    mutableStateOf(2)
}

val moreOrCollapseIndicator = @Composable { scope: ContextualFlowRowOverflowScope ->
    val remainingItems = totalCount - scope.shownItemCount
    ChipItem(if (remainingItems == 0) "Less" else "+$remainingItems", onClick = {
        if (remainingItems == 0) {
            maxLines = 2
        } else {
            maxLines += 5
        }
    })
}
ContextualFlowRow(
    modifier = Modifier
        .safeDrawingPadding()
        .fillMaxWidth(1f)
        .padding(16.dp)
        .wrapContentHeight(align = Alignment.Top)
        .verticalScroll(rememberScrollState()),
    verticalArrangement = Arrangement.spacedBy(4.dp),
    horizontalArrangement = Arrangement.spacedBy(8.dp),
    maxLines = maxLines,
    overflow = ContextualFlowRowOverflow.expandOrCollapseIndicator(
        minRowsToShowCollapse = 4,
        expandIndicator = moreOrCollapseIndicator,
        collapseIndicator = moreOrCollapseIndicator
    ),
    itemCount = totalCount
) { index ->
    ChipItem("Item $index")
}

Bağlamsal akış satırları örneği.
Şekil 2. ContextualFlowRow örneği

Ürün ağırlıkları

Ağırlık, bir öğenin boyutunu faktörüne ve yerleştirildiği satırdaki kullanılabilir alana göre büyütür. Önemli bir nokta, bir öğenin genişliğini hesaplamak için ağırlıkların nasıl kullanıldığıyla ilgili olarak FlowRow ve Row arasında bir fark olmasıdır. Rows için ağırlık Row içindeki tüm öğeleri temel alır. FlowRow ile ağırlık, FlowRow kapsayıcısındaki tüm öğelere değil, bir öğenin yerleştirildiği satırdaki öğelere dayanır.

Örneğin, hepsi bir satırda yer alan ve her biri farklı olan 4 öğeniz varsa 1f, 2f, 1f ve 3f ağırlıkları varsa toplam ağırlık 7f olur. Bir satır veya sütundaki kalan alan 7f'e bölünür. Bu durumda her bir öğe genişliği şu kullanılarak hesaplanmıştır: weight * (remainingSpace / totalWeight).

Izgara benzeri bir düzen oluşturmak için Modifier.weight ve max öğelerini FlowRow veya FlowColumn ile birlikte 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 neler yapabileceğinize dair birkaç farklı örnek vardır. Aşağıda gösterildiği gibi öğelerin eşit boyutta olduğu bir ızgara buna örnek gösterilebilir:

Akış satırı ile oluşturulan ızgara
Şekil 3. FlowRow ile ızgara oluşturma

Eşit öğe boyutlarına sahip bir ızgara oluşturmak için şunları 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 bunu 9 yerine 10 kez tekrarlarsanız tüm satırın toplam ağırlığı 1f olduğu için son öğe son sütunun tamamını kaplar:

Izgaradaki son öğe tam boyutta
Şekil 4. Son öğenin tam genişliği kapladığı bir ızgara oluşturmak için FlowRow kullanılıyor

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

Ayrıca, iki öğenin her birinin genişliğin yarısını, bir öğenin ise sonraki sütunun tüm genişliğini kapladığı, farklı öğe boyutlarından oluşan bir ızgara da oluşturabilirsiniz:

Akış satırlı alternatif ızgara
Şekil 5. FlowRow satır boyutları değişken

Bunu aşağıdaki kodla yapabilirsiniz:

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 kapsayıcı görevi görür. Bu, Modifier.fillMaxWidth(fraction)'ün Row veya Column'ye uygulandığındaki işleyişinden farklıdır. Row/Column öğeleri, kapsayıcının tüm genişliği yerine kalan genişliğin bir yüzdesini kaplar.

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

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 kadarını içeren orta öğe.

Akış satırlı kesirli genişlik

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

Satırlı kesirli genişlik

fillMaxColumnWidth() ve fillMaxRowHeight()

FlowColumn veya FlowRow içindeki bir öğeye Modifier.fillMaxColumnWidth() ya da Modifier.fillMaxRowHeight() uygulandığında, aynı sütundaki veya satırdaki öğelerin, sütundaki/satırdaki en büyük öğeyle aynı genişliği veya yüksekliği kaplaması sağlanır.

Örneğin, bu örnekte Android tatlılarının listesini görüntülemek için FlowColumn kullanılmaktadır. Öğelere Modifier.fillMaxColumnWidth() uygulandığında ve uygulanmadığında ve öğeler kaydırıldığında her bir öğenin genişliğindeki farkı 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()

dolguMaksimumSütunGenişliği

Genişlik değişikliği ayarlanmadı (sarmalanan öğeler)

Doldurulacak maksimum sütun genişliği ayarlanmadı