Özel düzenler

Oluşturma'da kullanıcı arayüzü öğeleri, çağrıldıklarında bir kullanıcı arayüzü bölümünü yayınlayan birleşik işlevlerle temsil edilir. Daha sonra, ekranda oluşturulan bir kullanıcı arayüzü ağacına eklenir. Her kullanıcı arayüzü öğesinin bir üst öğesi ve muhtemelen çok sayıda alt öğesi vardır. Her öğe de üst öğesi içinde, (x, y) konumu ve bir boyut olarak width ile height olarak belirtilir.

Üst öğeler, alt öğelerine ilişkin kısıtlamaları tanımlar. Bir öğenin boyutunu bu kısıtlamalar dahilinde tanımlaması istenir. Kısıtlamalar, bir öğenin minimum ve maksimum width ile height kullanımını kısıtlar. Bir öğenin alt öğeleri varsa boyutunu belirlemek için her alt öğeyi ölçebilir. Bir öğe kendi boyutunu tanımlayıp bildirdikten sonra, Özel düzenler oluşturma bölümünde ayrıntılı olarak açıklandığı üzere alt öğelerinin kendisine göre nasıl yerleştirileceğini tanımlama fırsatına sahiptir.

Kullanıcı arayüzü ağacındaki her düğümün yerleştirilmesi üç adımlı bir işlemdir. Her düğüm:

  1. Çocukları ölçme
  2. Kendi boyutuna karar verin
  3. Çocuklarını yerleştirme

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

Kapsam kullanımı, çocuklarınızı ne zaman ölçüp yerleştirebileceğinizi tanımlar. Bir düzeni yalnızca ölçüm ve düzen geçişleri sırasında ölçebilirsiniz. Alt öğe, yalnızca düzen geçişleri sırasında (ve yalnızca ölçülmesinden sonra) eklenebilir. MeasurementScope ve YerleşimKapsam gibi Yazma kapsamları nedeniyle bu işlem, derleme sırasında uygulanır.

Düzen değiştiriciyi kullanma

Bir öğenin ölçülme ve yerleştirilme şeklini değiştirmek için layout değiştiricisini kullanabilirsiniz. Layout bir lambdadır. Parametresi, measurable olarak iletilen ve bu kompozisyonun constraints olarak iletilebilecek gelen kısıtlamalarını 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 üstten metin metninin ilk satırına olan uzaklığı kontrol edelim. paddingFromBaseline değiştiricisinin işlevi tam olarak bu. Bunu bir örnek olarak burada uyguluyoruz. Bunu yapmak için besteyi ekrana manuel olarak yerleştirmek üzere layout değiştiricisini kullanın. Text üst dolgusu 24.dp olarak ayarlanan istenen davranış şöyledir:

Öğelerin arasındaki boşluğu ayarlayan normal kullanıcı arayüzü dolgusu ile alanı bir temelden diğerine ayarlayan metin dolgusu arasındaki farkı gösterir

Bu boşluğu oluşturmak için kullanılacak kodu aşağıda bulabilirsiniz:

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)
    }
}

Kodda neler olduğu aşağıda açıklanmaktadır:

  1. measurable lambda parametresinde, measurable.measure(constraints) yöntemini çağırarak ölçülebilir parametreyle gösterilen Text değerini ölçersiniz.
  2. Sarmalanmış öğeleri yerleştirmek için kullanılan bir lambda sağlayan layout(width, height) yöntemini çağırarak sıkıştırılabilir öğenin boyutunu belirtirsiniz. Bu durumda, son taban çizgi ile eklenen üst dolgu arasındaki yüksekliktir.
  3. Sarmalanmış öğeleri, placeable.place(x, y) yöntemini çağırarak ekrandaki konumlara yerleştirirsiniz. Sarmalanmış öğeler yerleştirilmezse bunlar görünmez. y konumu, en üst dolguya (metnin ilk başlangıç noktasının konumuna) karşılık gelir.

Bu özelliğin beklendiği gibi çalıştığını doğrulamak için Text üzerinde şu değiştiriciyi 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: Birinde öğeler arasında normal dolgu, diğerinde ise bir referans noktasından diğerine dolgu gösteriliyor

Özel düzenler oluşturma

layout değiştiricisi yalnızca çağrıyı birleştirir. Birden çok besteyi ölçmek ve düzenlemek için bunun yerine Layout bestesini kullanın. Bu şekilde, çocukları manuel olarak ölçebilir ve yerleştirebilirsiniz. Column ve Row gibi tüm üst düzey düzenler Layout kombinasyonuyla oluşturulur.

Column ürününün çok temel bir sürümünü oluşturalım. Çoğu özel düzende şu kalıp kullanılır:

@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 çocukların listesidir ve constraints, üst öğeden gelen kısıtlamalardır. Öncekiyle aynı mantığı takip eden MyBasicColumn, aşağıdaki gibi 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 besteler Layout kısıtlamalarıyla (minHeight kısıtlamaları olmadan) sınırlandırılır ve önceki bestenin yPosition değerine göre yerleştirilir.

Bu özel bestenin 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!")
    }
}

Birkaç metin öğesi, bir sütunda bir sonrakinin üzerine yığıldı.

Düzen yönü

LocalLayoutDirection kompozisyonunu yerel olarak bir bestenin düzen yönünü değiştirin.

Besteleri ekrana manuel olarak yerleştiriyorsanız LayoutDirection, layout değiştiricisinin veya Layout kompozitinin LayoutScope değerinin bir parçasıdır.

layoutDirection kullanırken place ile öğeler oluşturun. placeRelative yönteminin aksine place, düzen yönüne göre (soldan sağa veya sağdan sola) değişmez.

Özel düzenler iş başında

Oluşturma temel düzenleri bölümünde düzenler ve değiştiriciler hakkında daha fazla bilgi edinin ve özel düzenler oluşturan örnekler oluşturma bölümünde özel düzenleri uygulamalı olarak görün.

Daha fazla bilgi

Compose'daki özel düzenler hakkında daha fazla bilgi edinmek için aşağıdaki ek kaynakları inceleyin.

Videolar