Özel düzenler

Compose'da kullanıcı arayüzü öğeleri, çağrıldıklarında bir kullanıcı arayüzü parçası yayınlayan ve daha sonra ekranda oluşturulan bir kullanıcı arayüzü ağacına eklenen birleştirilebilir işlevlerle temsil edilir. Her kullanıcı arayüzü öğesinin bir üst öğesi ve muhtemelen çok sayıda alt öğesi vardır. Her öğe, ebeveyninde de bulunur. Bu öğelerin konumu (x, y) olarak, boyutu ise width ve height olarak belirtilir.

Ebeveynler, alt öğelerinin kısıtlamalarını tanımlar. Öğeden 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 belirledikten ve bildirdikten sonra, Özel düzenler oluşturma bölümünde ayrıntılı olarak açıklandığı gibi, alt öğelerinin kendisine göre nasıl yerleştirileceğini tanımlayabilir.

Kullanıcı arayüzü ağacındaki her bir düğümü düzenlemek üç adımdan oluşan bir işlemdir. Her düğüm:

  1. Alt öğeleri ölçün
  2. Kendi boyutunu belirleme
  3. Alt öğelerini yerleştirme

Düğüm düzeninin üç adımı: alt öğeleri ölçün, boyuta karar verin, alt öğeleri yerleştirin

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 ve bir 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 derleme kapsamları nedeniyle bu, derleme zamanında uygulanır.

Düzen değiştiriciyi kullanma

Bir öğenin ölçülüş ve düzenleniş şeklini değiştirmek için layout değiştiricisini kullanabilirsiniz. Layout bir lambda'dır; parametreleri, ölçebileceğiniz öğeyi (measurable olarak iletilir) ve bu derlenebilir öğenin gelen kısıtlamalarını (constraints olarak iletilir) içerir. Özel bir düzen değiştirici aşağıdaki gibi görünebilir:

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

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

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

Bu boşluğu oluşturacak kod aşağıda verilmiştir:

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)'yi çağırarak ölçülebilir parametreyle temsil edilen Text değerini ölçersiniz.
  2. layout(width, height) yöntemini çağırarak composable'ın boyutunu belirtirsiniz. Bu yöntem, sarmalanmış öğeleri yerleştirmek için kullanılan bir lambda da sağlar. Bu durumda, son taban çizgisi ile eklenen üst dolgu arasındaki yüksekliktir.
  3. placeable.place(x, y) işlevini çağırarak sarmalanmış öğeleri ekranda konumlandırırsınız. Sarmalanmış öğeler yerleştirilmezse görünmez. ykonumu, üst dolguya (metnin ilk yatay çizgisinin konumu) karşılık gelir.

Bunun beklendiği gibi çalıştığını doğrulamak için bu değiştiriciyi bir 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 çok önizlemesi; biri öğeler arasındaki normal dolguyu, diğeri ise bir taban çizgisinden diğerine dolguyu gösterir

Özel düzenler oluşturma

layout değiştiricisi yalnızca çağrıyı yapan bileşeni değiştirir. Birden fazla bileşeni ölçmek ve düzenlemek için bunun yerine Layout bileşenini kullanın. Bu bileşen, çocukları manuel olarak ölçmenize ve yerleştirmenize olanak tanır. Column ve Row gibi tüm üst düzey düzenler, Layout bileşeni ile oluşturulur.

Column işlevinin çok basit 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 bileşenler, Layout kısıtlamalarıyla (minHeight kısıtlamaları olmadan) sınırlanır ve önceki bileşenin yPosition değerine göre yerleştirilir.

Bu özel kompozisyonun 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 yığılmış birkaç metin öğesi.

Düzen yönü

LocalLayoutDirection bileşimini yerel olarak değiştirerek bir bileşimin düzen yönünü değiştirin.

Composable'ları ekrana manuel olarak yerleştiriyorsanız LayoutDirection, layout değiştiricinin veya Layout composable'ın LayoutScope parçasıdır.

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

Özel düzenler kullanımda

Oluşturma bölümündeki temel düzenler başlıklı makalede düzenler ve değiştiriciler hakkında daha fazla bilgi edinin. Özel düzenler oluşturan Oluşturma örnekleri başlıklı makalede ise özel düzenleri kullanımda görebilirsiniz.

Daha fazla bilgi

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

Videolar