Oluşturma değiştiriciler

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ş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 kaplıyor.

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, 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 yönergelerindeki Öğeler, 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
    }
}

Kenarlardaki dolgu dahil olmak üzere alanın tamamı tıklamalara yanıt verir

Yukarıdaki kodda, padding değiştiricisi clickable değiştiricisinden sonra uygulandığı için çevreleyen 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
    }
}

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

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

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 öğ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 öğ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 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)
        }
    }
}

Üstünde dolgu bulunan 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ştirici, 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ü.

Oluşturma'da kapsam güvenliği

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

Ö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 öğ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 üst düzenle aynı boyutta olmasını istiyorsanız matchParentSize düzenleyicisini 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()
    }
}

Kapsayıcısını 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

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 composable içeren bir Row düşünelim. İlk kutuya ikinci kutunun weight değerinin iki katı, dolayısıyla 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)
        ) {
            /*...*/
        }
    }
}

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

Değiştiricileri çıkarma ve yeniden kullanma

Bir bileşiği süslemek veya geliştirmek için birden fazla değiştirici birlikte zincirlenebilir. 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 ve grafik davranışları, tüm hareketle ilgili, odak ve anlambilim davranışları ve cihaz giriş etkinlikleri gibi ayrı bir davranışı temsil eder. 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 ç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 kodun temizliğini, tutarlılığını ve sürdürülebilirliğini teşvik eder kod tabanı boyunca

Değiştiricileri yeniden kullanmayla ilgili en iyi uygulamalar

Kendi Modifier zincirlerinizi oluşturup bunları çıkartıp birden fazla zincirde yeniden kullanın bileşenlerine ayıralım. 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 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 kompozisyon yapılabilir. 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, değiştiricinin aynı örneğini oluşturup ayıklayabilir, yeniden kullanabilir ve aşağıdaki gibi birleştirilebilir öğ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, ö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 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ştiricilerin sırasının önemli olduğunu unutmayın.

Daha fazla bilgi

Parametreleri ve kapsamlarıyla birlikte değişkenler için 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 Artık Android deposunda başlıklı makaleyi inceleyebilirsiniz.

Ö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.