Stillerle ilgili yapılması ve yapılmaması gerekenler

Bu sayfada, kod tabanınızda tutarlılık sağlayan stillerle çalışmaya yönelik en iyi uygulamaların yanı sıra API'leri tasarlarken izlediğimiz ilkeler açıklanmaktadır.

Yapılması gerekenler

Şu en iyi uygulamaları deneyin:

Yapılacaklar: Görseller için stilleri, davranışlar için değiştiricileri kullanın

Görsel yapılandırma (arka planlar, dolgu, kenarlıklar) için Styles API'yi kullanın ve değiştiricileri tıklama mantığı, hareket algılama veya erişilebilirlik gibi davranışlar için ayırın.

Yapılması gerekenler: Tasarım sistemlerinde stil parametrelerini kullanıma sunma

Kendi özel tasarım sistemi bileşenleriniz için değiştirici parametreden sonra bir Style nesnesi göstermeniz gerekir.

@Composable
fun GradientButton(
    modifier: Modifier = Modifier,
    // ✅ DO: for design system components, expose a style modifier to consumers to be able to customize the components
    style: Style = Style
) {
    // Consume the style
}

Yapılacaklar: Görsel tabanlı parametreleri bir Stille değiştirin

Composable'larınızdaki parametreleri tek bir Style parametresiyle değiştirmeyi düşünebilirsiniz. Örneğin:

// Before
@Composable
fun OldButton(background: Color, fontColor: Color) {
}

// After
// ✅ DO: Replace visual-based parameters with a style that includes same properties
@Composable
fun NewButton(style: Style = Style) {
}

Yapılacaklar: Animasyonlar için stillere öncelik verin

Değiştiricilere kıyasla performans artışı sağlayan animasyonlarla duruma dayalı stil oluşturmak için yerleşik animate bloğunu kullanın.

Yapılacaklar: "Son yazma kazanır" özelliğinden yararlanın.

style özelliklerinin yığılmak yerine üzerine yazılmasından yararlanın. Varsayılan bileşen kenarlıklarını veya arka planlarını birden fazla parametreye gerek kalmadan geçersiz kılmak için bunu kullanın.

Yapılmaması gerekenler

Aşağıdaki kalıpların kullanılması önerilmez:

Yapılmaması gerekenler: Etkileşim mantığı için stilleri kullanma

Bir stil içinde onClick veya hareket algılamayı işlemeye çalışmayın. Stiller, duruma dayalı görsel yapılandırmalarla sınırlıdır. Bu nedenle, iş mantığını işlememeli, bunun yerine yalnızca duruma göre farklı bir görsele sahip olmalıdır.

Yapılmaması gerekenler: Varsayılan parametre olarak varsayılan stil sağlama

Stil parametreleri her zaman style: Style = Style kullanılarak bildirilmelidir:

@Composable
fun BadButton(
    modifier: Modifier = Modifier,
    // ❌ DON'T set a default style here as a parameter
    style: Style = Style { background(Color.Red) }
) {
}

"Varsayılan" bir parametre eklemek için gelen parametre stilini tanımlanan varsayılanla birleştirin:

@Composable
fun GoodButton(
    modifier: Modifier = Modifier,
    // ✅ Do: always pass it as a Style, do not pass other defaults
    style: Style = Style
) {
    // ...
    val defaultStyle = Style { background(Color.Red) }
    // ✅ Do Combine defaults inside with incoming parameter
    Box(modifier = modifier.styleable(styleState, defaultStyle, style)) {
      // your logic
    }
}

Yapılmaması gerekenler: Düzen tabanlı composable'lara stil parametreleri sağlama

Herhangi bir composable'a stil sağlayabilirsiniz ancak düzen tabanlı composable'ların veya ekran düzeyindeki composable'ların stili kabul etmesi beklenmez. Bu düzeyde bir stilin ne yapacağı tüketici açısından net değildir. Stiller, düzenler için değil, bileşenler için tasarlanır.

Yapılmaması gerekenler: Kompozisyon'da stil oluşturma

CompositionLocals, stilin tanımlandığı noktada okunur, kullanıldığı noktada okunmaz. Stil gerçekten kullanıldığında CompositionLocal öğesinin durumu değişmiş olabilir ve bu da yanlış bir stile neden olur.

// DON'T - Create styles in Composition that access composition locals in this way - this will likely lead to issues when style is used / accessed, as it would not get updated when the value changes.
@Composable
fun containerStyle(): Style {
    val background = MaterialTheme.colorScheme.background
    val onBackground = MaterialTheme.colorScheme.onBackground
    return Style {
        background(background)
        contentColor(onBackground)
    }
}

// Do: Instead, Create StyleScope extension functions for your subsystems to access themed composition Locals
val StyleScope.colors: JetsnackColors
    get() = JetsnackTheme.LocalJetsnackTheme.currentValue.colors

val StyleScope.typography: androidx.compose.material3.Typography
    get() = JetsnackTheme.LocalJetsnackTheme.currentValue.typography
val StyleScope.shapes: Shapes
    get() = JetsnackTheme.LocalJetsnackTheme.currentValue.shapes
// Access CompositionLocals
val button = Style {
    background(colors.brandSecondary)
    shape(shapes.small)
}

Yapılacaklar: Alt sistem değeri değişiklikleri için bir stil oluşturun

Örneğin, koyu ve açık mod arasında geçiş yapılıyorsa CompositionLocal aracılığıyla mevcut temalı değerleri sorgulayarak Style değerini dinamik olarak değiştirebilirsiniz:

// Do: Use CompositionLocals or themed values to create a single style
val buttonStyle = Style {
    background(colors.brandSecondary)
    shape(shapes.small)
}

Yapılacaklar: Bileşen, tema tanımları arasında temel olarak farklılık gösterdiğinde stillerin tamamını değiştirin.

Temel olarak farklı temalar söz konusuysa tema düzeyinde stil nesnelerinin tamamını değiştirebilirsiniz.

Örneğin, ürün/sayfa veya teklif başına farklı temalara sahip bir uygulama oluşturuyorsanız ve bir Stilin birçok özelliği farklıysa tema düzeyinde stil kümelerinin tamamını değiştirebilirsiniz.

// DO Switch out whole styles when many properties differ - if Product A and Product B are two white labelled apps that provide different Themes.
val productBThemedButton = Style {
    shape(shapes.small)
    background(colors.brandSecondary)
    // other properties are fundamentally different
}

val productAThemedButton = Style {
    shape(shapes.large)
    background(colors.brand)
    // other properties are fundamentally different
}