ConstraintLayout, ekrandaki diğer composable'lara göre composable'ları yerleştirmenize olanak tanıyan bir düzendir. Bu, iç içe yerleştirilmiş birden fazla Row, Column, Box ve diğer özel düzen öğelerini kullanmaya alternatif bir yöntemdir. ConstraintLayout
Daha karmaşık hizalama gereksinimlerine sahip daha büyük düzenler uygularken kullanışlıdır.
Aşağıdaki senaryolarda ConstraintLayout kullanmayı düşünebilirsiniz:
- Kodun okunabilirliğini artırmak için öğeleri ekranda konumlandırmak üzere birden fazla
ColumnveRowiç içe yerleştirmekten kaçının. - Composable'ları diğer composable'lara göre veya kılavuzlara, bariyerlere ya da zincirlere göre konumlandırmak için kullanılır.
View sisteminde, düz görünüm hiyerarşisi iç içe yerleştirilmiş görünümlere kıyasla performans açısından daha iyi olduğundan büyük ve karmaşık düzenler oluşturmak için ConstraintLayout önerilen yöntemdi. Ancak bu durum, derin düzen hiyerarşilerini verimli bir şekilde işleyebilen Compose'da sorun teşkil etmez.
ConstraintLayout hizmetini kullanmaya başla
Oluşturma'da ConstraintLayout kullanmak için build.gradle'nize (Compose kurulumuna ek olarak) şu bağımlılığı eklemeniz gerekir:
implementation "androidx.constraintlayout:constraintlayout-compose:$constraintlayout_compose_version"
Oluşturma bölümündeki ConstraintLayout, DSL kullanılarak aşağıdaki şekilde çalışır:
createRefs()veyacreateRefFor()kullanarakConstraintLayoutiçindeki her composable için referans oluşturun.- Kısıtlamalar, referansı parametre olarak alan ve gövde lambda'sında kısıtlamalarını belirtmenize olanak tanıyan
constrainAs()değiştiricisi kullanılarak sağlanır. - Kısıtlamalar,
linkTo()veya diğer faydalı yöntemler kullanılarak belirtilir. parent,ConstraintLayoutcomposable'ın kendisiyle ilgili kısıtlamaları belirtmek için kullanılabilecek mevcut bir referanstır.
ConstraintLayout kullanan bir composable örneğini aşağıda bulabilirsiniz:
@Composable fun ConstraintLayoutContent() { ConstraintLayout { // Create references for the composables to constrain val (button, text) = createRefs() Button( onClick = { /* Do something */ }, // Assign reference "button" to the Button composable // and constrain it to the top of the ConstraintLayout modifier = Modifier.constrainAs(button) { top.linkTo(parent.top, margin = 16.dp) } ) { Text("Button") } // Assign reference "text" to the Text composable // and constrain it to the bottom of the Button composable Text( "Text", Modifier.constrainAs(text) { top.linkTo(button.bottom, margin = 16.dp) } ) } }
Bu kod, Button öğesinin üst kısmını 16.dp kenar boşluğuyla üst öğeye, Text öğesini de Button öğesinin alt kısmına 16.dp kenar boşluğuyla kısıtlar.
Button ve Text, ConstraintLayout içinde birbirine bağlı olarak oluşturulabilir.
Ayrılmış API
ConstraintLayout örneğinde kısıtlamalar, uygulandıkları composable'da bir değiştiriciyle birlikte satır içi olarak belirtilir. Ancak, kısıtlamaları uygulandıkları düzenlerden ayırmanın tercih edileceği durumlar da vardır. Örneğin, kısıtlamaları ekran yapılandırmasına göre değiştirmek veya iki kısıtlama grubu arasında animasyon oluşturmak isteyebilirsiniz.
Bu gibi durumlarda ConstraintLayout simgesini farklı bir şekilde kullanabilirsiniz:
ConstraintLayoutişlevine parametre olarakConstraintSetiletin.ConstraintSetiçinde oluşturulan referansları,layoutIddeğiştiricisini kullanarak composable'lara atayın.
@Composable fun DecoupledConstraintLayout() { BoxWithConstraints { val constraints = if (minWidth < 600.dp) { decoupledConstraints(margin = 16.dp) // Portrait constraints } else { decoupledConstraints(margin = 32.dp) // Landscape constraints } ConstraintLayout(constraints) { Button( onClick = { /* Do something */ }, modifier = Modifier.layoutId("button") ) { Text("Button") } Text("Text", Modifier.layoutId("text")) } } } private fun decoupledConstraints(margin: Dp): ConstraintSet { return ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") constrain(button) { top.linkTo(parent.top, margin = margin) } constrain(text) { top.linkTo(button.bottom, margin) } } }
Ardından, kısıtlamaları değiştirmeniz gerektiğinde farklı bir ConstraintSet iletebilirsiniz.
ConstraintLayout kavramları
ConstraintLayout, composable'ınızdaki öğeleri konumlandırmanıza yardımcı olabilecek yönergeler, engeller ve zincirler gibi kavramlar içerir.
Kurallar
Kılavuzlar, düzen tasarlarken kullanılan küçük görsel yardımcı araçlardır. Composable'lar bir kılavuz çizgisiyle sınırlandırılabilir. Kılavuzlar, öğeleri üst composable'ın içinde belirli bir dp veya percentage konumuna yerleştirmek için kullanışlıdır.
Dikey ve yatay olmak üzere iki farklı türde yönergeler vardır. Yatay olan iki düğme top ve bottom, dikey olan iki düğme ise start ve end'dir.
ConstraintLayout { // Create guideline from the start of the parent at 10% the width of the Composable val startGuideline = createGuidelineFromStart(0.1f) // Create guideline from the end of the parent at 10% the width of the Composable val endGuideline = createGuidelineFromEnd(0.1f) // Create guideline from 16 dp from the top of the parent val topGuideline = createGuidelineFromTop(16.dp) // Create guideline from 16 dp from the bottom of the parent val bottomGuideline = createGuidelineFromBottom(16.dp) }
Bir yönerge oluşturmak için createGuidelineFrom* ile gerekli yönerge türünü kullanın. Bu, Modifier.constrainAs() blokunda kullanılabilecek bir referans oluşturur.
Bariyerler
Barriers, belirtilen taraftaki en uç widget'a dayalı sanal bir kılavuz çizgisi oluşturmak için birden fazla composable'a referans verir.
Engel oluşturmak için createTopBarrier() (veya: createBottomBarrier(), createEndBarrier(), createStartBarrier()) simgesini kullanın ve engeli oluşturacak referansları girin.
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val topBarrier = createTopBarrier(button, text) } }
Daha sonra bariyer, Modifier.constrainAs() bloğunda kullanılabilir.
Zincirler
Zincirler, tek bir eksende (yatay veya dikey) grup benzeri davranış sağlar. Diğer eksen bağımsız olarak kısıtlanabilir.
Zincir oluşturmak için createVerticalChain veya createHorizontalChain simgesini kullanın:
ConstraintLayout { val constraintSet = ConstraintSet { val button = createRefFor("button") val text = createRefFor("text") val verticalChain = createVerticalChain(button, text, chainStyle = ChainStyle.Spread) val horizontalChain = createHorizontalChain(button, text) } }
Daha sonra zincir, Modifier.constrainAs() bloğunda kullanılabilir.
Bir zincir, birleştirilebilir öğeyi çevreleyen alanla nasıl başa çıkılacağını belirleyen farklı ChainStyles ile yapılandırılabilir. Örneğin:
ChainStyle.Spread: Boşluk, ilk composable'dan önceki ve son composable'dan sonraki boş alan da dahil olmak üzere tüm composable'lara eşit şekilde dağıtılır.ChainStyle.SpreadInside: Boşluk, tüm composable'lar arasında eşit olarak dağıtılır. İlk composable'dan önce veya son composable'dan sonra boş alan olmaz.ChainStyle.Packed: Boşluk, ilk birleştirilebilir öğeden önce ve son birleştirilebilir öğeden sonra dağıtılır. Birleştirilebilir öğeler, aralarında boşluk olmadan birbirine yakın şekilde yerleştirilir.
Daha fazla bilgi
ConstraintLayout kullanan beste örneklerinde, Beste'de ConstraintLayout ile ilgili daha fazla bilgi edinin.