Değiştiriciler, composable'ları süslemenize veya geliştirmenize olanak tanır. Değiştiriciler, aşağıdaki gibi şeyleri yapmanıza olanak tanır:
- composable'ın boyutunu, düzenini, davranışını ve görünümünü değiştirin
- Erişilebilirlik etiketleri gibi bilgiler ekleyin
- Kullanıcı girişini işle
- Bir öğeyi tıklanabilir, kaydırılabilir, sürüklenebilir veya yakınlaştırılabilir hale getirmek gibi üst düzey etkileşimler ekleme
Değiştiriciler standart Kotlin nesneleridir. 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 oluşturmak için zincir halinde kullanabilirsiniz:
@Composable private fun Greeting(name: String) { Column( modifier = Modifier .padding(24.dp) .fillMaxWidth() ) { Text(text = "Hello,") Text(text = name) } }
Yukarıdaki kodda, farklı değiştirici işlevlerinin birlikte kullanıldığına dikkat edin.
padding
bir öğenin etrafına boşluk yerleştirir.fillMaxWidth
, composable'ın üst öğesinden kendisine verilen maksimum genişliği doldurmasını sağlar.
En iyi uygulama olarak tüm composable'larınızın bir modifier
parametresini kabul etmesi ve bu değiştiriciyi, kullanıcı arayüzü yayınlayan ilk alt öğesine iletmeniz önerilir.
Bu, kodunuzu daha fazla yeniden kullanılabilir hale getirir ve davranışını daha tahmin edilebilir ve sezgisel hale getirir. Daha fazla bilgi için Compose API yönergelerine bakın ve Öğeler Değiştirici parametreyi kabul eder ve bu parametreyi dikkate alır.
Değiştiricilerin sırası önemlidir
Değiştirici işlevlerin sırası anlamlıdır. Her işlev, önceki işlev tarafından döndürülen Modifier
üzerinde değişiklikler yaptığından, sıra nihai sonucu etkiler. Bunun bir örneğini 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ştiriciden sonra uygulandığından alanın tamamını çevreleyen dolgu da dahil olmak üzere tıklanabilir özelliktedir. Değiştiricilerin sırası ters ç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 composable'ı süslemenize veya geliştirmenize yardımcı olacak yerleşik değiştiricilerin bir listesini sunar. Düzenlerinizi ayarlamak için kullanacağınız bazı yaygın değiştiricileri aşağıda bulabilirsiniz.
padding
ve size
Varsayılan olarak, Compose'da sağlanan düzenler 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 boyutun, düzenin üst öğesinden gelen kısıtlamaları karşılamıyorsa dikkate alınmayabileceğini unutmayın. composable boyutunun gelen kısıtlamalardan bağımsız olarak 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, height
üst öğesi 100.dp
olarak ayarlanmış olsa bile requiredSize
değiştiricisi öncelikli olduğu için Image
yüksekliği 150.dp
olur.
Bir alt düzenin üst öğe tarafından izin verilen tüm kullanılabilir yüksekliği doldurmasını istiyorsanız fillMaxHeight
değiştiricisini ekleyin (Oluşturma fillMaxSize
ve fillMaxWidth
değerlerini de sağlar):
@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 padding
değiştiricisi ayarlayın.
Düzenin tepesinden referans değere kadar belirli bir mesafeye ulaşmak için metin referans çizgisinin üstüne dolgu eklemek isterseniz 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 ekleyip x ve y eksenlerine ofseti ayarlayın.
Başlangıçlar pozitif olabileceği gibi pozitif de olmayabilir. padding
ile offset
arasındaki fark, bir composable'a offset
eklemenin ölçümlerini değiştirmemesidir:
@Composable fun ArtistCard(artist: Artist) { Row(/*...*/) { Column { Text(artist.name) Text( text = artist.lastSeenOnline, modifier = Modifier.offset(x = 4.dp) ) } } }
offset
değiştiricisi, düzenin yönüne göre yatay olarak uygulanır.
Soldan sağa bir bağlamda pozitif offset
, öğeyi sağa, sağdan sola bağlamda ise sola kaydırır.
Düzen 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ştiricisine bakın.
offset
değiştiricisi, ofsetleri parametre olarak alan offset
ve lambda alan offset
olmak üzere iki aşırı yükleme sağlar.
Bunların her birinin ne zaman kullanılacağı ve performans için nasıl optimize edileceği hakkında daha ayrıntılı bilgi için Performansı oluşturun - Mümkün olduğunca uzun süre okur bölümünü okuyun.
Compose'da kapsam güvenliği
Compose'da yalnızca belirli composable'ların alt öğelerine uygulandığında kullanılabilen değiştiriciler vardır. Oluşturma işlemi bunu özel kapsamlar aracılığıyla uygular.
Örneğin, Box
boyutunu etkilemeden Box
üst öğesi kadar büyük bir alt öğe yapmak istiyorsanız matchParentSize
değiştiricisini kullanın. matchParentSize
yalnızca BoxScope
dilinde kullanılabilir.
Bu nedenle, yalnızca Box
ebeveyni olan çocuklarda kullanılabilir.
Kapsam güvenliği, diğer composable'lar ve kapsamlarda işe yaramayacak değiştiriciler eklemenizi engeller ve deneme yanılma süreçlerinden size zaman kazandırır.
Kapsamlı değiştiriciler, üst yayıncının alt öğe hakkında bilmesi gereken bazı bilgiler hakkında üst tarafa bilgi verir. Bunlara genellikle üst veri değiştiriciler de denir. Dahili öğeleri genel amaçlı değiştiricilerden farklıdır, ancak kullanım açısından bakıldığında bu farklılıklar önemli değildir.
Box
dahilinde matchParentSize
tarihinde başlıyor
Yukarıda belirtildiği gibi, Box
boyutunu etkilemeden üst Box
ile aynı boyutta bir alt düzen olmasını istiyorsanız matchParentSize
değiştiricisini kullanın.
matchParentSize
öğesinin yalnızca Box
kapsamında kullanılabildiğini, yani yalnızca Box
composable'ın doğrudan alt öğeleri için geçerli olduğunu unutmayın.
Aşağıdaki örnekte Spacer
alt öğesi, boyutunu üst Box
öğesinden alır. Bu da 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ıldıysa Spacer
, üst öğe için izin verilen tüm alanı kaplar ve bunun sonucunda üst öğenin genişletilip kullanılabilir tüm alanı doldurmasına neden olur.
Row
ve Column
içinde weight
Dolgu ve boyut hakkındaki önceki bölümde gördüğünüz gibi, varsayılan olarak composable boyut, sarmaladığı içeriğe göre tanımlanır. Yalnızca RowScope
ve ColumnScope
ürünlerinde kullanılabilen weight
Değiştirici'yi kullanarak bir composable boyutunu üst öğesi içinde esnek olacak şekilde ayarlayabilirsiniz.
İki adet Box
composable içeren bir Row
ele alalım.
Birinci kutuya ikincinin weight
değerinin iki katı olarak genişliğin iki katı verilir. Row
, 210.dp
genişliğinde olduğundan ilk Box
140.dp
, 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 çıkarma ve yeniden kullanma
Birden çok değiştirici bir composable'ı süslemek veya güçlendirmek için birbirine zincirlenebilir. Bu zincir, tek bir Modifier.Elements
öğesinin sıralı ve sabit bir listesini temsil eden Modifier
arayüzü aracılığıyla oluşturulur.
Her Modifier.Element
; düzen, çizim ve grafik davranışları, hareketle ilgili, odak ve anlamsal davranışlar ve cihaz giriş etkinlikleri gibi bağımsız bir davranışı temsil eder. Bunların sıralaması önemlidir: İlk eklenen değiştirici
öğeler önce uygulanır.
Bazen aynı değiştirici zinciri örneklerini birden fazla composable'da ayıklamak ve daha yüksek kapsamlara çekmek yoluyla kullanmak faydalı olabilir. Birkaç nedenden dolayı kod okunabilirliğini iyileştirebilir veya uygulamanızın performansının iyileştirilmesine yardımcı olabilir:
- Düzenleyicileri kullanan composable'lar için yeniden oluşturma gerçekleştiğinde değiştiricilerin yeniden tahsisi tekrarlanmaz
- Değiştirici zincirler potansiyel olarak çok uzun ve karmaşık olabilir. Bu nedenle, aynı zincir örneğinin yeniden kullanılması, Compose çalışma zamanının bu zincirleri karşılaştırırken yapması gereken iş yükünü hafifletebilir
- Bu ayıklama işlemi, kod tabanı genelinde kod temizliğini, tutarlılığını ve bakımını sağlar.
Değiştiricileri yeniden kullanmayla ilgili en iyi uygulamalar
Kendi Modifier
zincirlerinizi oluşturun ve bunları birden fazla composable bileşende yeniden kullanmak için ayıklayın. Bir değiştiricinin kaydedilmesinde bir sakınca yoktur, çünkü bunlar veri benzeri nesnelerdir:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp)
Sık sık değişen durumu gözlemlerken değiştiricileri çıkarma ve yeniden kullanma
Animasyon durumları veya scrollState
gibi composable'ların içinde sık sık değişen durumlar gözlemlenirken, önemli miktarda yeniden oluşturma işlemi yapılmış olabilir. Bu durumda, değiştiricileriniz her yeniden oluşturmada ve potansiyel olarak her karede 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, aynı değiştirici örneğini oluşturabilir, ayıklayabilir ve yeniden kullanabilir, aşağıdaki şekilde composable'a aktarabilirsiniz:
// 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 ) }
Kapsamlı olmayan değiştiricileri çıkarma ve yeniden kullanma
Değiştiricilerin kapsamı belirli bir composable'a ayarlanabilir veya belirli bir composable'a ayarlanabilir. Kapsam dışı değiştiriciler söz konusu olduğunda, bunları herhangi bir composable'ın dışına basit değişkenler olarak kolayca çıkarabilirsiniz:
val reusableModifier = Modifier .fillMaxWidth() .background(Color.Red) .padding(12.dp) @Composable fun AuthorField() { HeaderText( // ... modifier = reusableModifier ) SubtitleText( // ... modifier = reusableModifier ) }
Bu, özellikle geç düzenlerle birlikte kullanıldığında faydalı olabilir. Çoğu durumda, potansiyel olarak önemli olan tüm öğelerinizin tam olarak aynı değiştiricilere sahip olmasını 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 çıkarma ve yeniden kullanma
Kapsamı belirli composable'lara ayarlanmış değiştiricileri işlerken bunları mümkün olan en üst düzeye çıkarabilir ve gerektiğinde 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 iletmelisiniz. Bu konunun neden önemli olduğu hakkında daha fazla referans için Oluşturma işleminde 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 başka zincirlere dahil edebilir 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ştiricilerin sırasının önemli olduğunu unutmayın!
Daha fazla bilgi
Parametreleri ve kapsamlarıyla birlikte değiştiricilerin tam listesini sunuyoruz.
Değiştiricilerin nasıl kullanılacağıyla ilgili daha fazla alıştırma yapmak için Compose codelab'deki temel düzenler üzerinden veya Now in Android deposuna da bakabilirsiniz.
Özel değiştiriciler ve bunları nasıl oluşturacağınız hakkında daha fazla bilgi için Özel düzenler - Düzen değiştiriciyi kullanma konulu dokümanlara göz atın.
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken görüntülenir
- Düzen oluşturma ile ilgili temel bilgiler
- Düzenleyici işlemleri {:#editor-actions}
- Özel düzenler {:#custom-layouts }