Değiştiriciler, bir bileşeni süslemenize veya geliştirmenize olanak tanır. Değiştiriciler aşağıdaki gibi işlemleri yapmanıza olanak tanır:
- Bileşenin boyutunu, düzenini, davranışını ve görünümünü değiştirme
- Erişilebilirlik etiketleri gibi bilgiler ekleme
- Kullanıcı girişini işleme
- Bir öğeyi tıklanabilir, kaydırılabilir, sürüklenebilir veya yakınlaştırılabilir hale getirme gibi üst düzey etkileşimler ekleyin
Değiştiriciler standart Kotlin nesneleridir. Aşağıdaki Modifier
sınıf işlevlerinden birini çağırarak bir değiştirici oluşturun:
@Composable private fun Greeting(name: String) { Column(modifier = Modifier.padding(24.dp)) { Text(text = "Hello,") Text(text = name) } }
Bu işlevleri birleştirerek oluşturabilirsiniz:
@Composable private fun Greeting(name: String) { Column( modifier = Modifier .padding(24.dp) .fillMaxWidth() ) { Text(text = "Hello,") Text(text = name) } }
Yukarıdaki kodda, birlikte kullanılan farklı değiştirici işlevlere dikkat edin.
padding
, bir öğenin etrafına boşluk ekler.fillMaxWidth
, birleştirilebilir öğenin ebeveyninden kendisine verilen maksimum genişliği doldurmasını sağlar.
Kompozit öğelerinizin tümünün bir modifier
parametresi kabul etmesi ve bu değiştiriciyi kullanıcı arayüzü yayınlayan ilk alt öğesine iletmesi en iyi uygulamadır.
Bu sayede kodunuz daha fazla yeniden kullanılabilir hale gelir ve davranışı daha tahmin edilebilir ve sezgisel olur. Daha fazla bilgi için Compose API kurallarının Öğeler bir Değiştirici parametresini kabul eder ve ona uyar bölümüne bakın.
Değiştiricilerin sırası önemlidir
Değiştirici işlevlerin sırası önemlidir. Her işlev, önceki işlev tarafından döndürülen Modifier
değerinde değişiklik yaptığından sıra, nihai sonucu etkiler. Bununla ilgili bir örnek inceleyelim:
@Composable fun ArtistCard(/*...*/) { val padding = 16.dp Column( Modifier .clickable(onClick = onClick) .padding(padding) .fillMaxWidth() ) { // rest of the implementation } }
Yukarıdaki kodda, padding
değiştiricisi clickable
değiştiricisinden sonra uygulandığı için çevredeki dolgu dahil olmak üzere alanın tamamı tıklanabilir. Değiştirici sırası tersine çevrilirse padding
tarafından eklenen boşluk kullanıcı girişine tepki vermez:
@Composable fun ArtistCard(/*...*/) { val padding = 16.dp Column( Modifier .padding(padding) .clickable(onClick = onClick) .fillMaxWidth() ) { // rest of the implementation } }
Yerleşik değiştiriciler
Jetpack Compose, bir bileşeni süslemenize veya geliştirmenize yardımcı olacak yerleşik değiştiricilerin bir listesini sağlar. Aşağıda, düzenleri ayarlamak için kullanacağınız bazı yaygın değiştiriciler verilmiştir.
padding
ve size
Oluşturma bölümünde sağlanan düzenler varsayılan olarak alt öğelerini sarmalar. Ancak size
değiştiricisini kullanarak bir boyut ayarlayabilirsiniz:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image(/*...*/) Column { /*...*/ } } }
Belirttiğiniz boyut, düzenin üst öğesinden gelen kısıtlamaları karşılamıyorsa dikkate alınmayabilir. Gelen kısıtlamalardan bağımsız olarak birleştirilebilir boyutun sabitlenmesini istiyorsanız requiredSize
değiştiricisini kullanın:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image( /*...*/ modifier = Modifier.requiredSize(150.dp) ) Column { /*...*/ } } }
Bu örnekte, üst öğe height
100.dp
olarak ayarlanmış olsa bile requiredSize
değiştiricisi öncelikli olduğundan Image
öğesinin yüksekliği 150.dp
olur.
Bir alt düzenin, üst öğenin izin verdiği tüm yüksekliği doldurmasını istiyorsanız fillMaxHeight
değiştiricisini ekleyin (Oluşturma'da fillMaxSize
ve fillMaxWidth
de sağlanır):
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.size(width = 400.dp, height = 100.dp) ) { Image( /*...*/ modifier = Modifier.fillMaxHeight() ) Column { /*...*/ } } }
Bir öğenin etrafına dolgu eklemek için bir padding
değiştirici ayarlayın.
Bir metin yatay çizgisinin üzerine, düzenin üst kısmından yatay çizgiye belirli bir mesafe olacak şekilde dolgu eklemek istiyorsanız paddingFromBaseline
değiştiricisini kullanın:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text( text = artist.name, modifier = Modifier.paddingFromBaseline(top = 50.dp) ) Text(artist.lastSeenOnline) } } }
Zaman farkı
Bir düzeni orijinal konumuna göre konumlandırmak için offset
değiştiricisini ekleyin ve x ile y ekseninde ofseti ayarlayın.
Ofsetler pozitif veya pozitif olmayan olabilir. padding
ile offset
arasındaki fark, bir bileşiğe offset
eklendiğinde ölçümlerinin değişmemesidir:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text(artist.name) Text( text = artist.lastSeenOnline, modifier = Modifier.offset(x = 4.dp) ) } } }
offset
değiştirici, düzen yönüne göre yatay olarak uygulanır.
Soldan sağa bağlamında pozitif bir offset
, öğeyi sağa kaydırır. Sağdan sola bağlamında ise öğeyi sola kaydırır.
Sayfa düzeni yönünü dikkate almadan bir ofset ayarlamanız gerekiyorsa pozitif bir ofset değerinin öğeyi her zaman sağa kaydırdığı absoluteOffset
değiştiriciye bakın.
offset
değiştirici, iki aşırı yükleme sağlar: Ofsetleri parametre olarak alan offset
ve lambda alan offset
.
Bunların her birinin ne zaman kullanılacağı ve performans için nasıl optimize edileceği hakkında daha ayrıntılı bilgi edinmek için Oluşturma performansı - Okuma işlemlerini mümkün olduğunca erteleme bölümünü okuyun.
Oluşturma'da kapsam güvenliği
Oluşturma'da, yalnızca belirli derlenebilir öğelerin alt öğelerine uygulandığında kullanılabilen değiştiriciler vardır. Oluşturma, özel kapsamlar aracılığıyla bunu zorunlu kılar.
Örneğin, Box
boyutunu etkilemeden bir alt öğeyi Box
öğesi kadar büyük yapmak istiyorsanız matchParentSize
değiştiricisini kullanın. matchParentSize
yalnızca BoxScope
'de kullanılabilir.
Bu nedenle, yalnızca Box
üst öğesi altındaki bir alt öğede kullanılabilir.
Kapsam güvenliği, diğer bileşimlerde ve kapsamlarda çalışmayacak değiştiriciler eklemenizi önler ve deneme yanılma sürecinden tasarruf etmenizi sağlar.
Kapsamlı değiştiriciler, ebeveyni çocuk hakkında bilmesi gereken bazı bilgiler hakkında bilgilendirir. Bunlara genellikle üst veri değiştiriciler denir. Bu işlevlerin iç yapısı, genel amaçlı değiştiricilerden farklıdır ancak kullanım açısından bu farklılıklar önemli değildir.
matchParentSize
Box
içinde başlıyor
Yukarıda belirtildiği gibi, bir alt düzenin Box
boyutunu etkilemeden Box
üst düzeniyle aynı boyutta olmasını istiyorsanız matchParentSize
değiştiricisini kullanın.
matchParentSize
'ün yalnızca Box
kapsamında kullanılabildiğini unutmayın. Yani yalnızca Box
bileşenlerinin doğrudan alt öğeleri için geçerlidir.
Aşağıdaki örnekte, Spacer
alt öğesi boyutunu Box
üst öğesinden alır. Box
ise boyutunu en büyük alt öğeden (bu örnekte ArtistCard
) alır.
@Composable fun MatchParentSizeComposable() { Box { Spacer( Modifier .matchParentSize() .background(Color.LightGray) ) ArtistCard() } }
matchParentSize
yerine fillMaxSize
kullanılmış olsaydı Spacer
, ebeveyne izin verilen tüm alanı kaplar ve ebeveynin genişlemesine ve mevcut tüm alanı doldurmasına neden olurdu.
Row
ve Column
konumunda weight
Dolgu ve boyut ile ilgili önceki bölümde gördüğünüz gibi, varsayılan olarak birleştirilebilir boyut, sarmaladığı içerik tarafından tanımlanır. Yalnızca RowScope
ve ColumnScope
'de kullanılabilen weight
değiştiriciyi kullanarak bir composable boyutunu üst öğesi içinde esnek olacak şekilde ayarlayabilirsiniz.
İki Box
bileşeni içeren bir Row
alalım.
İlk kutuya ikinci kutunun weight
değerinin iki katı, yani genişliğin iki katı verilir. Row
210.dp
genişliğinde olduğundan ilk Box
140.dp
genişliğinde, ikincisi ise 70.dp
genişliğindedir:
@Composable fun ArtistCard(/*...*/) { Row( modifier = Modifier.fillMaxWidth() ) { Image( /*...*/ modifier = Modifier.weight(2f) ) Column( modifier = Modifier.weight(1f) ) { /*...*/ } } }
Değiştiricileri ayıklama ve yeniden kullanma
Bir bileşiği süslemek veya geliştirmek için birden fazla değiştirici birlikte zincirlenebilir. Bu zincir, tek bir Modifier.Elements
öğesinin sıralı ve değiştirilemez bir listesini temsil eden Modifier
arayüzü aracılığıyla oluşturulur.
Her Modifier.Element
, düzen, çizim ve grafik davranışları, tüm hareketle ilgili, odak ve anlambilim davranışları ve cihaz giriş etkinlikleri gibi ayrı bir davranışı temsil eder. Sıralama önemlidir: Önce eklenen değiştirici öğeler önce uygulanır.
Bazen aynı değiştirici zinciri örneklerini birden fazla bileşimde yeniden kullanmak, bunları değişkenlere ayırarak ve daha yüksek kapsamlara taşıyarak yararlı olabilir. Kod okunabilirliğini artırabilir veya uygulamanızın performansını iyileştirmeye yardımcı olabilir. Bunun birkaç nedeni vardır:
- Değiştiricilerin yeniden alımı, bunları kullanan kompozisyonlar için yeniden kompozisyon oluştuğunda tekrarlanmaz.
- Değiştirici zincirleri çok uzun ve karmaşık olabilir. Bu nedenle, aynı zincir örneğini yeniden kullanmak, Compose çalışma zamanında zincirleri karşılaştırırken yapması gereken iş yükünü azaltabilir.
- Bu ayıklama işlemi, kod tabanında kod temizliğini, tutarlılığı ve sürdürülebilirliği destekler.
Değiştiricileri yeniden kullanmayla ilgili en iyi uygulamalar
Kendi Modifier
zincirlerinizi oluşturun ve bunları birden fazla birleştirilebilir bileşende yeniden kullanmak için ayıklayın. Veri benzeri nesneler oldukları için değiştiricileri yalnızca kaydetmenizde herhangi bir sakınca yoktur:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp)
Sık değişen durumu gözlemlerken değiştiricileri ayıklayıp yeniden kullanma
Animasyon durumları veya scrollState
gibi, bileşenler içinde sık sık değişen durumlar gözlemlendiğinde önemli miktarda yeniden derleme yapılabilir. Bu durumda, değiştiricileriniz her yeniden oluşturma işleminde ve muhtemelen her kare için ayrılır:
@Composable fun LoadingWheelAnimation() { val animatedState = animateFloatAsState(/*...*/) LoadingWheel( // Creation and allocation of this modifier will happen on every frame of the animation! modifier = Modifier .padding(12.dp) .background(Color.Gray), animatedState = animatedState ) }
Bunun yerine, değiştiricinin aynı örneğini oluşturup ayıklayabilir, yeniden kullanabilir ve aşağıdaki gibi derlenen öğeye iletebilirsiniz:
// Now, the allocation of the modifier happens here: val reusableModifier = Modifier .padding(12.dp) .background(Color.Gray) @Composable fun LoadingWheelAnimation() { val animatedState = animateFloatAsState(/*...*/) LoadingWheel( // No allocation, as we're just reusing the same instance modifier = reusableModifier, animatedState = animatedState ) }
Kapsamsız değiştiricileri ayıklayıp yeniden kullanma
Değiştiricilerin kapsamı kaldırılabilir veya belirli bir bileşiğe göre belirlenebilir. Kapsamsız değiştiricileri, basit değişkenler olarak tüm derlenebilir öğelerin dışından kolayca ayıklayabilirsiniz:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) @Composable fun AuthorField() { HeaderText( // ... modifier = reusableModifier ) SubtitleText( // ... modifier = reusableModifier ) }
Bu özellik, özellikle yavaş düzenlerle birlikte kullanıldığında yararlı olabilir. Çoğu durumda, önemli miktarda öğenizin tümü için tam olarak aynı değiştiricileri kullanmak istersiniz:
val reusableItemModifier = Modifier .padding(bottom = 12.dp) .size(216.dp) .clip(CircleShape) @Composable private fun AuthorList(authors: List<Author>) { LazyColumn { items(authors) { AsyncImage( // ... modifier = reusableItemModifier, ) } } }
Kapsamlı değiştiricileri ayıklayıp yeniden kullanma
Belirli bir derlenebilir öğeyle kapsamlı olan değiştiricilerle çalışırken bunları mümkün olan en yüksek düzeye ayıklayabilir ve uygun olduğunda yeniden kullanabilirsiniz:
Column(/*...*/) { val reusableItemModifier = Modifier .padding(bottom = 12.dp) // Align Modifier.Element requires a ColumnScope .align(Alignment.CenterHorizontally) .weight(1f) Text1( modifier = reusableItemModifier, // ... ) Text2( modifier = reusableItemModifier // ... ) // ... }
Ayıklanan, kapsamlı değiştiricileri yalnızca aynı kapsamlı, doğrudan alt öğelere iletmeniz gerekir. Bunun neden önemli olduğu hakkında daha fazla bilgi için Oluşturma'da kapsam güvenliği bölümüne bakın:
Column(modifier = Modifier.fillMaxWidth()) { // Weight modifier is scoped to the Column composable val reusableItemModifier = Modifier.weight(1f) // Weight will be properly assigned here since this Text is a direct child of Column Text1( modifier = reusableItemModifier // ... ) Box { Text2( // Weight won't do anything here since the Text composable is not a direct child of Column modifier = reusableItemModifier // ... ) } }
Ayıklanan değiştiricilerin daha fazla zincirlenmesi
.then()
işlevini çağırarak ayıklanan değiştirici zincirlerinizi daha da zincirleyebilir veya ekleyebilirsiniz:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) // Append to your reusableModifier reusableModifier.clickable { /*...*/ } // Append your reusableModifier otherModifier.then(reusableModifier)
Değişkenlerin sırasının önemli olduğunu unutmayın.
Daha fazla bilgi
Parametreleri ve kapsamlarıyla birlikte değişkenleri içeren tam bir liste sunuyoruz.
Değiştiricileri kullanmayla ilgili daha fazla alıştırma yapmak için Compose codelab'deki temel düzenler başlıklı makaleyi inceleyebilir veya Now in Android deposuna göz atabilirsiniz.
Özel değiştiriciler ve bunların nasıl oluşturulacağı hakkında daha fazla bilgi için Özel düzenler - Düzen değiştiriciyi kullanma başlıklı dokümanları inceleyin.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Düzen oluşturmayla ilgili temel bilgiler
- Düzenleyici işlemleri {:#editor-actions}
- Özel düzenler {:#custom-layouts }