Stilleri kullanarak uygulamalarınızı geliştirmenin çeşitli yolları vardır. Seçiminiz, uygulamanızın Materyal Tasarım'ı benimseme durumuyla ilgili olarak nerede yer aldığına bağlıdır:
- Materyal Tasarım'ın kullanılmadığı, tamamen özel tasarım sistemi
- Öneri: Temadaki değerleri kullanan bileşen stilleri tanımlayın ve tasarım sistemi bileşenlerinde stil parametrelerini kullanıma sunun.
- Materyal Tasarım'ı kullanma
- Öneri: Stiller ile entegrasyon için Material'ın kullanılmasını bekleyin. Mümkün olduğunda kendi bileşenlerinizde stiller kullanın.
Stil katmanı
Geleneksel oluşturma modelinde özelleştirme genellikle MaterialTheme tarafından sağlanan genel jetonların (renkler ve tipografi) geçersiz kılınmasına veya mümkün olduğunda bir tasarım sistemi composable'ının özelliklerinin sarmalanıp geçersiz kılınmasına dayanır.
Bazen, malzeme katmanında alt sistemler veya parametreler aracılığıyla kullanıma sunulmayan ancak bileşenin kendisinde sabit kodlanmış varsayılanlar olan özellikler bulunur.
Styles API ile alt sistemler ve bileşenler arasında köprü görevi gören yeni bir soyutlama katmanı olan Styles'ı kullanabilirsiniz.
| Katman | Sorumluluk | Örnek |
|---|---|---|
| Alt sistem değerleri | Adlandırılmış değerler | val Primary = Color(0xFF34A85E) |
| Atomic Styles | Tam olarak bir özellik değişikliği yapan stil | val buttonStyle = paddingAtomic then roundedCornerShapeAtomic then primaryBackgroundAtomic then largeSize then interactiveShadowAtomic |
| Bileşen Stilleri | Bileşene özgü yapılandırmalar | Birincil arka plan ve 16 dp dolguya sahip bir düğme. val buttonStyle = Style { contentPadding(16.dp) shape(RoundedCornerShape(8.dp)) background(Color.Blue) } |
| Bileşenler | Stili kullanan işlevsel kullanıcı arayüzü öğesi. | Button(style = buttonStyle) { ... } |
Atomik ve monolitik stiller
Styles API ile bir stili ayrı atomik stillere ayırabilirsiniz.
baseButtonStyle gibi karmaşık, bileşene özgü stiller tanımlamak yerine küçük, tek amaçlı yardımcı stiller de oluşturabilirsiniz. Bunlar "atomlarınız" olarak kabul edilir.
// Define single-purpose "atomic" styles val paddingAtomic = Style { contentPadding(16.dp) } val roundedCornerShapeAtomic = Style { shape(RoundedCornerShape(8.dp)) } val primaryBackgroundAtomic = Style { background(Color.Blue) } val largeSizeAtomic = Style { size(100.dp, 40.dp) } val interactiveShadowAtomic = Style { hovered { animate { dropShadow( Shadow( offset = DpOffset( 0.dp, 0.dp ), radius = 2.dp, spread = 0.dp, color = Color.Blue, ) ) } } }
"Sonra" bağlacının kullanıldığı kompozisyonlar
Yeni Styles API'nin güçlü özelliklerinden biri, birden fazla Style nesneyi birleştirmenize olanak tanıyan then operatörüdür. Bu sayede, atomik yardımcı sınıfları kullanarak bir bileşen oluşturabilirsiniz.
Geleneksel (atomik olmayan):
// One large monolithic style val buttonStyle = Style { contentPadding(16.dp) shape(RoundedCornerShape(8.dp)) background(Color.Blue) }
Atomik yeniden düzenleme:
// Combine atoms to create the final appearance val buttonStyle = paddingAtomic then roundedCornerShapeAtomic then primaryBackgroundAtomic then interactiveShadowAtomic
Tasarım sisteminizde stilleri kullanma
Tasarım sisteminizde stilleri kullanırken, tasarım sisteminizin spektrumda bulunduğu yere bağlı olarak aşağıdaki seçenekleri göz önünde bulundurun.
Stillerle özel tasarım sistemi
Ne zaman kullanmalısınız? Material Design'a dayanmayan kapsamlı bir marka kılavuzu aldınız ve Material Design'ı kullanmayı planlamıyorsunuz.
Strateji: Tamamen özel bir tasarım sistemi uygulayın ve stilleri temanın bir parçası olarak kullanıma sunun.
Bu seçenek, ana tasarım sistemi diliniz olarak Material'ı kullanmıyorsanız özel yoldur. Görsel tanımlar için MaterialTheme'ı tamamen atlıyor ve kendi özel temanızı zaten oluşturmuş oluyorsunuz. Stilleriniz için kapsayıcı görevi gören bir CompanyTheme oluşturursunuz.
- İşleyiş şekli: Sisteminizdeki her bileşen için
Stylenesnelerini içeren birCompanyThemenesnesi oluşturun. Bileşenleriniz (Material mantığı etrafındaki sarmalayıcılar veya özelBoxya daLayoutuygulamaları) bu stilleri doğrudan kullanır ve tasarım sisteminizin tüketicileri için birStyleparametresi sunar. - Stil katmanı: Stiller, tasarım sisteminizin temel tanımıdır. Jetonlar, bu stillere aktarılan adlandırılmış değişkenlerdir. Bu, durum değişiklikleri için benzersiz animasyonlar tanımlama (örneğin, basıldığında ölçeği ve rengi animasyonla değiştirme) gibi derin özelleştirmelere olanak tanır.
Material'ı kullanmadan kendi özel temanızı oluşturuyorsanız ve stilleri kullanmak istiyorsanız stil listenizi temanıza ekleyin. Bu sayede, temel stillerinize projenizin herhangi bir yerinden erişebilirsiniz.
Uygulamanızdaki çeşitli stilleri depolayan bir
Stylessınıfı oluşturun ve varsayılanları oluşturun. Örneğin, Jetsnack uygulamasında sınıfın adıJetsnackStyles:object JetsnackStyles{ val buttonStyle: Style = Style { shape(shapes.medium) background(colors.brand) contentColor(colors.textPrimary) contentPaddingVertical(8.dp) contentPaddingHorizontal(24.dp) textStyle(typography.labelLarge) disabled { animate { background(colors.brandSecondary) } } } val cardStyle: Style = Style { shape(shapes.medium) background(colors.uiBackground) contentColor(colors.textPrimary) } }
Genel temanızın bir parçası olarak
Stylessağlayın ve alt sistemlere erişmek içinStyleScopeüzerinde yardımcı uzantı işlevlerini kullanıma sunun:@Immutable class JetsnackTheme( val colors: JetsnackColors = LightJetsnackColors, val typography: androidx.compose.material3.Typography = androidx.compose.material3.Typography(), val shapes: Shapes = Shapes() ) { companion object { val colors: JetsnackColors @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.colors val typography: androidx.compose.material3.Typography @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.typography val shapes: Shapes @Composable @ReadOnlyComposable get() = LocalJetsnackTheme.current.shapes val styles: JetsnackStyles = JetsnackStyles val LocalJetsnackTheme: ProvidableCompositionLocal<JetsnackTheme> get() = LocalJetsnackThemeInstance } } val StyleScope.colors: JetsnackColors get() = LocalJetsnackTheme.currentValue.colors val StyleScope.typography: androidx.compose.material3.Typography get() = LocalJetsnackTheme.currentValue.typography val StyleScope.shapes: Shapes get() = LocalJetsnackTheme.currentValue.shapes internal val LocalJetsnackThemeInstance = staticCompositionLocalOf { JetsnackTheme() } @Composable fun JetsnackTheme(darkTheme: Boolean = isSystemInDarkTheme(), content: @Composable () -> Unit) { val colors = if (darkTheme) DarkJetsnackColors else LightJetsnackColors val theme = JetsnackTheme(colors = colors) CompositionLocalProvider( LocalJetsnackTheme provides theme, ) { MaterialTheme( typography = LocalJetsnackTheme.current.typography, shapes = LocalJetsnackTheme.current.shapes, content = content, ) } }
Composable işlevinizde
JetsnackStylesöğesine erişin:@Composable fun CustomButton(modifier: Modifier, style: Style = Style, text: String) { val interactionSource = remember { MutableInteractionSource() } val styleState = remember(interactionSource) { MutableStyleState(interactionSource) } // Apply style to top level container in combination with incoming style from parameter. Box(modifier = modifier .clickable( interactionSource = interactionSource, indication = null, enabled = true, role = Role.Button, onClick = { }, ) .styleable(styleState, JetsnackTheme.styles.buttonStyle, style)) { Text(text) } }
Küresel tema kullanımının yanı sıra, uygulamalarınıza Styles eklemek için alternatif stratejiler de vardır. Belirli arama siteleri için Styles satır içi özelliğinden yararlanabilir veya tam temalandırma özellikleri gerekmeyen durumlarda statik tanımlar kullanabilirsiniz.
Styles, stilin tamamı temelde farklı olmadığı sürece koşullu olarak değiştirilmemelidir. Ayrı stil nesneleri arasında geçiş yapmak yerine, görsel tanım içinde dinamik jetonlara erişmeyi tercih etmelisiniz.