Oluşturma değiştiriciler

Değiştiriciler, bir composable'ı süslemenizi veya zenginleştirmenizi sağlar. Değiştiriciler şunları yapmanıza olanak tanır: bir şeyler var:

  • composable'ın 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şle
  • Bir öğeyi tıklanabilir, kaydırılabilir hale getirme gibi üst düzey etkileşimler ekleyin. sürüklenebilir veya yakınlaştırılabilir

Değiştiriciler, standart Kotlin nesneleridir. Aşağıdakilerden birini çağırarak bir değiştirici oluşturun: Modifier sınıf işlevleri:

@Composable
private fun Greeting(name: String) {
    Column(modifier = Modifier.padding(24.dp)) {
        Text(text = "Hello,")
        Text(text = name)
    }
}

Renkli bir arka plan üzerinde, metnin etrafında dolgu içeren iki satır metin.

İşlevleri birbirine bağlayarak oluşturmak için şu zincirleri kullanabilirsiniz:

@Composable
private fun Greeting(name: String) {
    Column(
        modifier = Modifier
            .padding(24.dp)
            .fillMaxWidth()
    ) {
        Text(text = "Hello,")
        Text(text = name)
    }
}

Metnin arkasındaki renkli arka plan artık cihazın tüm genişliğini gösteriyor.

Yukarıdaki kodda, farklı değiştirici işlevlerinin birlikte kullanıldığına dikkat edin.

  • padding, bir öğenin etrafına boşluk bırakır.
  • fillMaxWidth, composable'ın, kendisine verilen maksimum genişliği doldurmasını sağlar üst öğesi olabilir.

Tüm composable'larınızın bir modifier kabul etmesini sağlamak parametresini kullanın ve bu değiştiriciyi, kullanıcı arayüzü yayan ilk alt öğesine iletin. Böylece, ve davranışını daha öngörülebilir ve sezgisel hale getirir. Örneğin, daha fazla bilgi için Compose API yönergelerine bakın, Öğeler, bir öğeyi Değiştirici parametre.

Değiştiricilerin sırası önemlidir

Değiştirici işlevlerin sırası önemlidir. Her fonksiyon Modifier işlevindeki değişiklikler, önceki işlev tarafından döndürülen dizi nihai sonucu etkiler. Şimdi bir örnek inceleyelim:

@Composable
fun ArtistCard(/*...*/) {
    val padding = 16.dp
    Column(
        Modifier
            .clickable(onClick = onClick)
            .padding(padding)
            .fillMaxWidth()
    ) {
        // rest of the implementation
    }
}

Kenarların çevresindeki dolgu dahil olmak üzere tüm alan tıklamalara yanıt verir

Yukarıdaki kodda, çevresi de dahil olmak üzere tüm alanın tıklanabilir olması padding değiştiricisi clickable etiketinden sonra uygulandığı için dolgu kullanabilirsiniz. Değiştiricilerin 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
    }
}

Düzenin kenarının etrafındaki dolgu artık tıklamalara yanıt vermiyor

Yerleşik değiştiriciler

Jetpack Compose, dekorasyon veya dekorasyona yardımcı olan yerleşik değiştiricilerden oluşan bir liste sunar. composable'ı güçlendiriyor. Reklam öğelerinizi ayarlamak için kullanacağınız düzenler.

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 { /*...*/ }
    }
}

Bu boyutun karşılanmaması durumunda, belirttiğiniz boyuta uyulmayabileceğini unutmayın düzenin üst öğesinden gelen kısıtlamalarla ilgilidir. composable'a ihtiyacınız varsa, gelen kısıtlamalardan bağımsız olarak sabitlenecek boyutu değiştirmek için requiredSize değiştirici:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.requiredSize(150.dp)
        )
        Column { /*...*/ }
    }
}

Alt resim, üst öğesinden gelen kısıtlamalardan daha büyük

Bu örnekte, üst height 100.dp olarak ayarlanmış olsa bile requiredSize değiştiricisi alırken Image 150.dp olacak önceliklendirme.

Bir alt düzenin üst öğesi yerine, fillMaxHeight değiştiricisini ekleyin (Compose ayrıca fillMaxSize ve fillMaxWidth):

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.size(width = 400.dp, height = 100.dp)
    ) {
        Image(
            /*...*/
            modifier = Modifier.fillMaxHeight()
        )
        Column { /*...*/ }
    }
}

Resim yüksekliği, üst resmin yüksekliği kadar olmalıdır

Bir öğenin etrafına dolgu eklemek için padding değiştiricisini ayarlayın.

Metin referansının üstüne dolgu eklemek isterseniz düzenin üst kısmından temel çizgisine kadar belirli bir mesafeyi görmek için paddingFromBaseline değiştirici:

@Composable
fun ArtistCard(artist: Artist) {
    Row(/*...*/) {
        Column {
            Text(
                text = artist.name,
                modifier = Modifier.paddingFromBaseline(top = 50.dp)
            )
            Text(artist.lastSeenOnline)
        }
    }
}

Dolgulu metin

Zaman farkı

Bir düzeni orijinal konumuna göre konumlandırmak için offset değiştiricisini tıklayın ve x ile y eksenindeki ofseti ayarlayın. Kaydırmalar pozitif olduğu kadar pozitif olmayabilir de. Artımlılık ile ilişkilendirme padding ve offset, bir composable'a offset eklemenin nasıl değiştireceğini düşünün:

@Composable
fun ArtistCard(artist: Artist) {
    Row(/*...*/) {
        Column {
            Text(artist.name)
            Text(
                text = artist.lastSeenOnline,
                modifier = Modifier.offset(x = 4.dp)
            )
        }
    }
}

Metin, üst kapsayıcısının sağ tarafına kaydırıldı

offset değiştiricisi, düzen yönüne göre yatay olarak uygulanır. Soldan sağa bir bağlamda pozitif bir offset, öğeyi ise sağdan sola bağlamda öğeyi sola kaydırır. Düzen yönünü dikkate almadan bir ofset ayarlamanız gerekirse absoluteOffset değiştiricisi, pozitif bir ofset değerinin her zaman öğeyi sağ.

offset değiştiricisi iki aşırı yükleme sağlar: offset ofsetleri parametre olarak ve bir lambda alan offset. Bunlardan her birinin ne zaman kullanılacağı ve daha fazla bilgi edinmek için Performans oluşturma - Okumaları mümkün olduğunca uzun ertele bölümü.

Compose'da kapsam güvenliği

Oluşturma'da yalnızca çocuklara uygulandığında kullanılabilen değiştiriciler vardır belirli composable'ların Compose, bunu özel kapsamlar aracılığıyla uygular.

Örneğin, bir çocuğu ebeveyn kadar büyük yapmak istiyorsanız Box Box boyutunu etkiliyorsa matchParentSize kullanabilirsiniz. matchParentSize yalnızca şuralarda kullanılabilmektedir: BoxScope Bu nedenle, yalnızca Box üst grubundaki bir alt yayıncıda kullanılabilir.

Kapsam güvenliği, diğer tarayıcılarda çalışmayacak değiştiricileri eklemenizi hem de deneme ve yanılma yoluyla zaman tasarrufu sağlar.

Kapsamlı değiştiriciler, üst öğeyi bazı bilgiler hakkında ebeveyne bildirir düşünmesi gerekir. Bunlar yaygın olarak üst veri değiştiricileri ekleyin. Dahili işlevleri genel amaçtan farklıdır. kullanım açısından bakıldığında bu farklılıklar fark etmez.

matchParentSize Box içinde başlıyor

Yukarıda belirtildiği gibi, bir alt düzenin üst öğe ile aynı boyutta olmasını istiyorsanız Box boyutunu etkilemeden Box için matchParentSize değiştiriciyi kullanın.

matchParentSize öğesinin yalnızca Box kapsamında kullanılabildiğini unutmayın. Bu, yalnızca Box composable'ların doğrudan alt öğeleri için geçerlidir.

Aşağıdaki örnekte Spacer alt öğesi, boyutunu Box olan üst öğesinden alıyor. Bu da, boyutunu en büyük çocuklara göre alır. Bu örnekte ArtistCard.

@Composable
fun MatchParentSizeComposable() {
    Box {
        Spacer(
            Modifier
                .matchParentSize()
                .background(Color.LightGray)
        )
        ArtistCard()
    }
}

Kapsayıcıyı dolduran gri arka plan

matchParentSize yerine fillMaxSize kullanılsaydı Spacer ebeveyn için izin verilen kullanılabilir alanın tamamını oluşturur; bu da, genişletip mevcut alanı doldurun.

Ekranı kaplayan gri arka plan

Row ve Column içinde weight

Önceki bölümde gördüğünüz gibi Dolgu ve boyut, bir composable'ın varsayılan olarak emin olun. Bir composable'ın bu boyutun yalnızca RowScope içinde mevcut olan weight Değiştiriciyi kullanan ve ColumnScope.

İki Box composable içeren bir Row düşünelim. İlk kutu, ikincinin weight oranının iki katı olduğundan bu kutuya iki kat daha fazla dokunun. Row, 210.dp genişliğinde olduğundan ilk Box genişliği 140.dp ve ikincisi 70.dp:

@Composable
fun ArtistCard(/*...*/) {
    Row(
        modifier = Modifier.fillMaxWidth()
    ) {
        Image(
            /*...*/
            modifier = Modifier.weight(2f)
        )
        Column(
            modifier = Modifier.weight(1f)
        ) {
            /*...*/
        }
    }
}

Resim genişliği, metin genişliğinin iki katı

Değiştiricileri çıkarma ve yeniden kullanma

Birden fazla değiştiriciyi süslemek veya süslemek için birbirine zincirlenebilir composable'ı güçlendiriyor. Bu zincir, Modifier arayüzü aracılığıyla oluşturuldu Bu, tek Modifier.Elements öğesinin sıralı ve sabit bir listesini temsil eder.

Her Modifier.Element, düzen, çizim gibi bireysel bir davranışı temsil eder ve grafik davranışları, hareketle ilgili tüm, odaklanma ve anlamsal davranışlar ve cihaz giriş etkinlikleri. Bunların sıralaması önemlidir: etkili değiştirici önce eklenenler uygulanır.

Bazı durumlarda, aynı değiştirici zinciri örneklerini aynı anahtar kelimede composable'ları değişkenlere ayırarak ve bunları yüksek olabilir. Kod okunabilirliğini iyileştirebilir veya uygulamanızın birkaç nedenden dolayı:

  • Yeniden düzenleme gerçekleştiğinde değiştiricilerin yeniden tahsisi tekrarlanmaz bunun parçası olarak
  • Değiştirici zincirleri potansiyel olarak çok uzun ve karmaşık olabileceğinden, aynı zincir örneğinin Compose çalışma zamanının yapması gereken iş yükünü hafifletebileceği bunları daha kolay
  • Bu ayıklama işlemi kodun temizliğini, tutarlılığını ve sürdürülebilirliğini teşvik eder kod tabanı boyunca

Değiştiricileri yeniden kullanmak için en iyi uygulamalar

Kendi Modifier zincirlerinizi oluşturup bunları çıkartıp birden fazla zincirde yeniden kullanın bileşenlerine ayıralım. Değiştiriciyi kaydedebilirsiniz çünkü 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 gibi composable'ların içinde sık sık değişen durumları gözlemlerken veya scrollState durumunda, çok sayıda yeniden düzenleme olabilir. tamamlandı. Bu durumda, değiştiricileriniz her yeniden oluşturmada ayrılacaktır her karede izlemesi mümkün.

@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 kullanabilirsiniz ve bunu şu şekilde composable'a iletin:

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

Kapsamı belirlenmemiş değiştiricileri çıkarma ve yeniden kullanma

Değiştiricilerin kapsamı değişebilir veya belirli bir composable'dan bahsetmek istiyorum. Kapsamlı olmayan değiştiriciler söz konusu olduğunda bunları kolayca ayıklayabilirsiniz dışında basit bir değişken oluşturun:

val reusableModifier = Modifier
    .fillMaxWidth()
    .background(Color.Red)
    .padding(12.dp)

@Composable
fun AuthorField() {
    HeaderText(
        // ...
        modifier = reusableModifier
    )
    SubtitleText(
        // ...
        modifier = reusableModifier
    )
}

Bu, özellikle Tembel düzenlerle birleştirildiğinde yararlı olabilir. Çoğu zaman olması durumunda, potansiyel olarak önemli miktarda öğelerinizin tümünün tam olarak aynı değiştiricileri kullanın:

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ştiricilerle çalışırken, Bu dosyaları mümkün olan en üst düzeye çıkarın ve uygun olduğunda tekrar kullanın:

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

Çıkarılan, kapsamlı değiştiricileri yalnızca doğrudan etkili çocuklardır. Daha fazla bilgi için Kapsam güvenliği Bunun neden önemli olduğuna dair daha fazla referans için şu bilgileri oluşturun:

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

Çıkarılan değiştiricilerde daha fazla zincirleme

Ayıklanan değiştirici zincirlerinizi daha fazla zincir haline getirmek veya ekleyebilirsiniz. Bunun için .then() işlevi:

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

Değiştiricilerin tam listesini aşağıda bulabilirsiniz. emin olmanız gerekir.

Değiştiricileri nasıl kullanacağınızla ilgili daha fazla alıştırma için Compose codelab'deki temel düzenler veya Şimdi Android deposunda.

Ö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 ile ilgili dokümanlara göz atın.

ziyaret edin.