Özel düzenler

Compose'da kullanıcı arayüzü öğeleri, çağrıldığında bir kullanıcı arayüzü parçası yayan ve ardından ekranda oluşturulan bir kullanıcı arayüzü ağacına eklenen composable işlevlerle temsil edilir. Her kullanıcı arayüzü öğesinin bir üst öğesi ve muhtemelen birçok alt öğesi vardır. Her öğe, üst öğesinin içinde yer alır. Konum (x, y) olarak, boyut ise width ve height olarak belirtilir.

Ebeveynler, alt öğeleri için kısıtlamalar tanımlar. Bir öğenin, bu kısıtlamalar dahilinde boyutunu tanımlaması istenir. Kısıtlamalar, bir öğenin minimum ve maksimum width ve height değerlerini kısıtlar. Bir öğenin alt öğeleri varsa boyutunu belirlemek için her alt öğeyi ölçebilir. Bir öğe kendi boyutunu belirleyip bildirdikten sonra, Özel düzenler oluşturma bölümünde ayrıntılı olarak açıklandığı gibi alt öğelerini kendisine göre nasıl yerleştireceğini tanımlayabilir.

Kullanıcı arayüzü ağacındaki her düğümü yerleştirmek üç adımlı bir süreçtir. Her düğüm:

  1. Alt öğeleri ölçme
  2. Kendi boyutuna karar verir.
  3. Alt öğelerini yerleştirme

Düğüm yerleşiminin üç adımı: çocukları ölçme, boyuta karar verme, çocukları yerleştirme

Kapsamların kullanımı, çocuklarınızı ne zaman ölçebileceğinizi ve yerleştirebileceğinizi tanımlar. Bir düzenin ölçümü yalnızca ölçüm ve düzen geçişleri sırasında yapılabilir. Alt öğe yalnızca düzen geçişleri sırasında (ve yalnızca ölçüldükten sonra) yerleştirilebilir. MeasureScope ve PlacementScope gibi Compose kapsamları nedeniyle bu, derleme zamanında zorunlu kılınır.

Düzen değiştiriciyi kullanma

Bir öğenin nasıl ölçülüp yerleştirileceğini değiştirmek için layout değiştiricisini kullanabilirsiniz. Layout bir lambda'dır. Parametreleri arasında, measurable olarak iletilen ve ölçebileceğiniz öğe ile constraints olarak iletilen bu composable'ın gelen kısıtlamaları yer alır. Özel düzen değiştirici aşağıdaki gibi görünebilir:

fun Modifier.customLayoutModifier() =
    layout { measurable, constraints ->
        // ...
    }

Ekranda Text karakterini gösterelim ve üst kısımdan ilk metin satırının taban çizgisine olan mesafeyi kontrol edelim. paddingFromBaseline değiştiricisi tam olarak bunu yapar. Burada örnek olarak uyguluyoruz. Bunu yapmak için layout değiştiricisini kullanarak composable'ı ekrana manuel olarak yerleştirin. Text Üst dolgunun ayarlandığı 24.dp istenen davranış aşağıda verilmiştir:

Öğeler arasındaki boşluğu ayarlayan normal kullanıcı arayüzü dolgusu ile bir temel çizgiden diğerine boşluk ayarlayan metin dolgusu arasındaki farkı gösterir.

Bu aralığı oluşturmak için gereken kod:

fun Modifier.firstBaselineToTop(
    firstBaselineToTop: Dp
) = layout { measurable, constraints ->
    // Measure the composable
    val placeable = measurable.measure(constraints)

    // Check the composable has a first baseline
    check(placeable[FirstBaseline] != AlignmentLine.Unspecified)
    val firstBaseline = placeable[FirstBaseline]

    // Height of the composable with padding - first baseline
    val placeableY = firstBaselineToTop.roundToPx() - firstBaseline
    val height = placeable.height + placeableY
    layout(placeable.width, height) {
        // Where the composable gets placed
        placeable.placeRelative(0, placeableY)
    }
}

Bu kodda neler oluyor?

  1. measurable lambda parametresinde, measurable.measure(constraints) çağrısı yaparak ölçülebilir parametreyle gösterilen Text değerini ölçersiniz.
  2. Sarmalanmış öğeleri yerleştirmek için kullanılan bir lambda da sağlayan layout(width, height) yöntemini çağırarak composable'ın boyutunu belirtirsiniz. Bu durumda, son temel çizgi ile eklenen üst dolgu arasındaki yükseklik söz konusudur.
  3. Sarmalanmış öğeleri ekranda placeable.place(x, y) çağırarak konumlandırırsınız. Sarmalanmış öğeler yerleştirilmezse görünmez. yKonum, üst dolguya (metnin ilk temel çizgisinin konumu) karşılık gelir.

Bu değiştiricinin beklendiği gibi çalıştığını doğrulamak için Text üzerinde kullanın:

@Preview
@Composable
fun TextWithPaddingToBaselinePreview() {
    MyApplicationTheme {
        Text("Hi there!", Modifier.firstBaselineToTop(32.dp))
    }
}

@Preview
@Composable
fun TextWithNormalPaddingPreview() {
    MyApplicationTheme {
        Text("Hi there!", Modifier.padding(top = 32.dp))
    }
}

Metin öğelerinin birden fazla önizlemesi. Birinde öğeler arasında normal dolgu, diğerinde ise bir temel çizgiden diğerine dolgu gösteriliyor.

Özel düzenler oluşturma

layout değiştiricisi yalnızca arama composable'ını değiştirir. Birden fazla composable'ı ölçmek ve yerleştirmek için bunun yerine Layout composable'ını kullanın. Bu composable, alt öğeleri manuel olarak ölçmenize ve yerleştirmenize olanak tanır. Column ve Row gibi tüm üst düzey düzenler Layout composable ile oluşturulur.

Column'nın çok temel bir sürümünü oluşturalım. Çoğu özel düzen şu kalıbı izler:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // measure and position children given constraints logic here
        // ...
    }
}

layout değiştiricisine benzer şekilde, measurables ölçülmesi gereken alt öğelerin listesi, constraints ise üst öğeden gelen kısıtlamalardır. Öncekiyle aynı mantıkla MyBasicColumn şu şekilde uygulanabilir:

@Composable
fun MyBasicColumn(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        modifier = modifier,
        content = content
    ) { measurables, constraints ->
        // Don't constrain child views further, measure them with given constraints
        // List of measured children
        val placeables = measurables.map { measurable ->
            // Measure each children
            measurable.measure(constraints)
        }

        // Set the size of the layout as big as it can
        layout(constraints.maxWidth, constraints.maxHeight) {
            // Track the y co-ord we have placed children up to
            var yPosition = 0

            // Place children in the parent layout
            placeables.forEach { placeable ->
                // Position item on the screen
                placeable.placeRelative(x = 0, y = yPosition)

                // Record the y co-ord placed up to
                yPosition += placeable.height
            }
        }
    }
}

Alt composable'lar Layout kısıtlamalarıyla (minHeight kısıtlamaları olmadan) sınırlandırılır ve önceki composable'ın yPosition değerine göre yerleştirilir.

Bu özel composable'ın nasıl kullanılacağı aşağıda açıklanmıştır:

@Composable
fun CallingComposable(modifier: Modifier = Modifier) {
    MyBasicColumn(modifier.padding(8.dp)) {
        Text("MyBasicColumn")
        Text("places items")
        Text("vertically.")
        Text("We've done it by hand!")
    }
}

Bir sütunda üst üste yerleştirilmiş birkaç metin öğesi.

Düzen yönü

LocalLayoutDirection kompozisyon yerelini değiştirerek bir composable'ın düzen yönünü değiştirin.

Composable'ları ekrana manuel olarak yerleştiriyorsanız LayoutDirection, layout değiştiricisinin veya Layout composable'ının LayoutScope bölümüdür.

layoutDirection kullanırken place kullanarak composable'ları yerleştirin. placeRelative yönteminin aksine, place düzen yönüne (soldan sağa ve sağdan sola) göre değişmez.

Kullanımdaki özel düzenler

Compose'da temel düzenler başlıklı makaleden düzenler ve değiştiriciler hakkında daha fazla bilgi edinin. Ayrıca, Özel düzenler oluşturan Compose örnekleri başlıklı makaleden özel düzenlerin nasıl kullanıldığını inceleyin.

Daha fazla bilgi

Oluşturma'daki özel düzenler hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynaklara göz atın.

Videolar