Özel düzenler

Compose'da kullanıcı arayüzü öğeleri, çağrıldığında bir kullanıcı arayüzü parçası yayan ve daha sonra ekranda oluşturulan 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 birçok alt öğesi vardır. Her bir öğe ayrıca (x, y) konumu olarak belirtilen bir üst öğesi içinde ve width ile height olarak belirtilen bir boyut içinde yer alır.

Üst öğeler, alt öğeleri için kısıtlamaları tanımlar. Bir öğ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 belirlemeye yardımcı olmak için her bir 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 öğelerinin kendisine göre nasıl yerleştirileceğini tanımlama fırsatına sahip olur.

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

  1. Çocukları ölçün
  2. Kendi boyutunu belirleyin
  3. Alt öğelerini yerleştir

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

Kapsamların kullanımı, çocuklarınızı ne zaman ölçebileceğinizi ve yerleştirebileceğinizi tanımlar. Bir düzen yalnızca ölçüm ve düzen geçişleri sırasında ölçülebilir. Çocuk yalnızca düzen geçişleri sırasında (ve yalnızca ölçüldükten sonra) yerleştirilebilir. MeasurementScope ve PlacementScope gibi Compose kapsamları nedeniyle bu, derleme sırasında uygulanır.

Düzen değiştiriciyi kullanma

Bir öğenin ölçülme ve düzenlenme şeklini değiştirmek için layout değiştiricisini kullanabilirsiniz. Layout bir lambdadır. Bu öğenin parametreleri, ölçebileceğiniz öğeyi measurable olarak iletir ve bu birleştirilebilir öğenin gelen kısıtlamalarını constraints olarak iletir. Özel bir düzen değiştiricisi şöyle görünebilir:

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

Ekranda bir Text görüntüleyelim ve metnin ilk satırının üstten taban çizgisine olan mesafeyi kontrol edelim. paddingFromBaseline değiştiricisinin yaptığı iş tam olarak budur. Bunu bir örnek olarak burada uyguluyoruz. Böylece, beste dosyasını ekrana manuel olarak yerleştirmek için layout değiştiricisini kullanın. Text üst dolgusu 24.dp olarak ayarlandığında istenen davranış şu şekildedir:

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

Bu boşluğu oluşturmak için gereken kod şudur:

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 olduğu aşağıda açıklanmıştır:

  1. measurable lambda parametresinde, ölçülebilir parametreyle temsil edilen Text parametresini measurable.measure(constraints) çağırarak ölçersiniz.
  2. composable'ın boyutunu, layout(width, height) yöntemini çağırarak belirtirsiniz. Bu yöntem, sarmalanmış öğelerin yerleştirilmesi için kullanılan bir lambda sağlar. Bu durumda, son referans çizgisi ile eklenen üst dolgu arasındaki yüksekliktir.
  3. Ekrandaki sarmalanmış öğeleri placeable.place(x, y) çağırarak konumlandırırsınız. Sarmalanmış öğeler yerleştirilmezse görünmezler. y konumu, üst dolguya, yani metnin ilk referansının konumuna karşılık gelir.

Bunun 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; bir tanesi öğeler arasındaki normal dolguyu, diğeri ise bir referans değerden diğerine dolguyu gösterir

Özel düzenler oluşturma

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

Column için çok temel bir sürüm 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 listesidir. constraints ise üst öğeden gelen kısıtlamalardır. Önceki mantığı aynı şekilde, 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 besteler Layout kısıtlamalarıyla (minHeight kısıtlamaları olmadan) kısıtlanır ve önceki oluşturulan öğenin yPosition değerine göre yerleştirilir.

Bu özel beste öğesinin 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 bir sonrakinin üzerine yığılmış birkaç metin öğesi.

Düzen yönü

LocalLayoutDirection bestesini yerel olarak değiştirerek bir beste öğesinin düzen yönünü değiştirin.

Kompozisyonları ekrana manuel olarak yerleştiriyorsanız LayoutDirection öğesi, layout değiştiricideki LayoutScope öğesinin veya composable Layout öğesinin bir parçasıdır.

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

Özel düzenlerin işleyiş şekli

Oluşturma işleminde temel düzenler bölümünde düzenler ve değiştiriciler hakkında daha fazla bilgi edinin. Özel düzenler oluşturan örnekler oluşturma bölümünde özel düzenlerin işleyiş şeklini görebilirsiniz.

Daha fazla bilgi

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

Videolar