Materyal, önerilen tasarım sistemimizdir ve Jetpack Compose, Materyal'in bir uygulamasını sunar ancak bu sistemi kullanmak zorunda değilsiniz. Materyaller tamamen herkese açık API'ler üzerine kurulu olduğundan aynı şekilde kendi tasarım sisteminizi de oluşturabilirsiniz.
Bu konuda uygulayabileceğiniz birkaç yaklaşım vardır:
- Ek tema değerleriyle
MaterialTheme
'ı genişletme - Bir veya daha fazla Material sistemini (
Colors
,Typography
veyaShapes
) özel uygulamalarla değiştirirken diğerlerini koruma MaterialTheme
'yi değiştirmek için tamamen özel bir tasarım sistemi uygulama
Materyal bileşenlerini özel bir tasarım sistemiyle kullanmaya devam etmek de isteyebilirsiniz. Bunu yapmak mümkündür ancak uyguladığınız yaklaşıma uymak için aklınızda bulundurmanız gereken noktalar vardır.
MaterialTheme
ve özel tasarım sistemleri tarafından kullanılan alt düzey yapıları ve API'leri hakkında daha fazla bilgi edinmek için Oluşturma'daki bir temanın anatomisi kılavuzuna göz atın.
Materyal temasını genişletme
Compose Material, Material yönergelerine uymayı basit ve tür açısından güvenli hale getirmek için Material tema oluşturma özelliğini yakından modeller. Ancak renk, yazı tipi ve şekil gruplarını ek değerlerle genişletebilirsiniz.
En basit yaklaşım, uzantı mülkleri eklemektir:
// Use with MaterialTheme.colorScheme.snackbarAction val ColorScheme.snackbarAction: Color @Composable get() = if (isSystemInDarkTheme()) Red300 else Red700 // Use with MaterialTheme.typography.textFieldInput val Typography.textFieldInput: TextStyle get() = TextStyle(/* ... */) // Use with MaterialTheme.shapes.card val Shapes.card: Shape get() = RoundedCornerShape(size = 20.dp)
Bu, MaterialTheme
kullanım API'leriyle tutarlılık sağlar. Compose tarafından tanımlanan bu tür bir parametreye örnek olarak, yüksekliğe bağlı olarak kullanılması gereken yüzey rengini belirleyen surfaceColorAtElevation
verilebilir.
Diğer bir yaklaşım, MaterialTheme
ve değerlerini "sarmalayan" genişletilmiş bir tema tanımlamaktır.
Mevcut malzeme renklerini korurken iki ek renk (caution
ve onCaution
, yarı tehlikeli işlemler için kullanılan sarı bir renk) eklemek istediğinizi varsayalım:
@Immutable data class ExtendedColors( val caution: Color, val onCaution: Color ) val LocalExtendedColors = staticCompositionLocalOf { ExtendedColors( caution = Color.Unspecified, onCaution = Color.Unspecified ) } @Composable fun ExtendedTheme( /* ... */ content: @Composable () -> Unit ) { val extendedColors = ExtendedColors( caution = Color(0xFFFFCC02), onCaution = Color(0xFF2C2D30) ) CompositionLocalProvider(LocalExtendedColors provides extendedColors) { MaterialTheme( /* colors = ..., typography = ..., shapes = ... */ content = content ) } } // Use with eg. ExtendedTheme.colors.caution object ExtendedTheme { val colors: ExtendedColors @Composable get() = LocalExtendedColors.current }
Bu, MaterialTheme
kullanım API'lerine benzer. ExtendedTheme
öğelerini MaterialTheme
ile aynı şekilde iç içe yerleştirebileceğiniz için birden fazla temayı da destekler.
Material bileşenlerini kullanma
Materyal temalandırma genişletilirken mevcut MaterialTheme
değerleri korunur ve Materyal bileşenleri makul varsayılan değerlere sahip olmaya devam eder.
Bileşenlerde genişletilmiş değerleri kullanmak istiyorsanız bunları kendi composable işlevlerinize sarmalayın, değiştirmek istediğiniz değerleri doğrudan ayarlayın ve diğerlerini kapsayıcı composable'a parametre olarak gösterin:
@Composable fun ExtendedButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( containerColor = ExtendedTheme.colors.caution, contentColor = ExtendedTheme.colors.onCaution /* Other colors use values from MaterialTheme */ ), onClick = onClick, modifier = modifier, content = content ) }
Daha sonra, uygun durumlarda Button
kullanımlarını ExtendedButton
ile değiştirirsiniz.
@Composable fun ExtendedApp() { ExtendedTheme { /*...*/ ExtendedButton(onClick = { /* ... */ }) { /* ... */ } } }
Materyal alt sistemlerini değiştirme
Materyal Temaları oluşturmak yerine bir veya daha fazla sistemi (Colors
, Typography
veya Shapes
) özel bir uygulamayla değiştirirken diğerlerini de koruyabilirsiniz.
Renk sistemini korurken tür ve şekil sistemlerini değiştirmek istediğinizi varsayalım:
@Immutable data class ReplacementTypography( val body: TextStyle, val title: TextStyle ) @Immutable data class ReplacementShapes( val component: Shape, val surface: Shape ) val LocalReplacementTypography = staticCompositionLocalOf { ReplacementTypography( body = TextStyle.Default, title = TextStyle.Default ) } val LocalReplacementShapes = staticCompositionLocalOf { ReplacementShapes( component = RoundedCornerShape(ZeroCornerSize), surface = RoundedCornerShape(ZeroCornerSize) ) } @Composable fun ReplacementTheme( /* ... */ content: @Composable () -> Unit ) { val replacementTypography = ReplacementTypography( body = TextStyle(fontSize = 16.sp), title = TextStyle(fontSize = 32.sp) ) val replacementShapes = ReplacementShapes( component = RoundedCornerShape(percent = 50), surface = RoundedCornerShape(size = 40.dp) ) CompositionLocalProvider( LocalReplacementTypography provides replacementTypography, LocalReplacementShapes provides replacementShapes ) { MaterialTheme( /* colors = ... */ content = content ) } } // Use with eg. ReplacementTheme.typography.body object ReplacementTheme { val typography: ReplacementTypography @Composable get() = LocalReplacementTypography.current val shapes: ReplacementShapes @Composable get() = LocalReplacementShapes.current }
Materyal bileşenlerini kullanma
Bir veya daha fazla MaterialTheme
sistemi değiştirildiğinde, Malzeme
bileşenlerinin olduğu gibi kullanılması istenmeyen Malzeme rengi, tür veya şekil değerlerine yol açabilir.
Bileşenlerde değiştirme değerleri kullanmak istiyorsanız bunları kendi composable işlevlerinize sarmalayın, ilgili sistem için değerleri doğrudan ayarlayın ve diğerlerini, kapsayıcı composable'a parametre olarak sunun.
@Composable fun ReplacementButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( shape = ReplacementTheme.shapes.component, onClick = onClick, modifier = modifier, content = { ProvideTextStyle( value = ReplacementTheme.typography.body ) { content() } } ) }
Ardından, uygun durumlarda Button
kullanımlarını ReplacementButton
ile değiştirirsiniz.
@Composable fun ReplacementApp() { ReplacementTheme { /*...*/ ReplacementButton(onClick = { /* ... */ }) { /* ... */ } } }
Tamamen özel bir tasarım sistemi uygulama
Material Theming'i tamamen özel bir tasarım sistemiyle değiştirmek isteyebilirsiniz.
MaterialTheme
kapsamında aşağıdaki sistemlerin sunulduğunu göz önünde bulundurun:
Colors
,Typography
veShapes
: Materyal Teması Oluşturma sistemleriTextSelectionColors
:Text
veTextField
tarafından metin seçimi için kullanılan renklerRipple
veRippleTheme
:Indication
için malzeme uygulaması
Material bileşenlerini kullanmaya devam etmek istiyorsanız istenmeyen davranışları önlemek için özel temanızdaki veya temalarınızdaki bu sistemlerin bazılarını değiştirmeniz ya da bileşenlerinizdeki sistemleri yönetmeniz gerekir.
Ancak tasarım sistemleri, Material'ın temel aldığı kavramlarla sınırlı değildir. Diğer kavramları temalarla uyumlu hale getirmek için mevcut sistemleri değiştirebilir ve yeni sınıflar ve türlerle tamamen yeni sistemler kullanabilirsiniz.
Aşağıdaki kodda, degradeler (List<Color>
) içeren özel bir renk sistemi modelliyoruz, bir tür sistemi ekliyoruz, yeni bir yükseklik sistemi tanıtıyoruz ve MaterialTheme
tarafından sağlanan diğer sistemleri hariç tutuyoruz:
@Immutable data class CustomColors( val content: Color, val component: Color, val background: List<Color> ) @Immutable data class CustomTypography( val body: TextStyle, val title: TextStyle ) @Immutable data class CustomElevation( val default: Dp, val pressed: Dp ) val LocalCustomColors = staticCompositionLocalOf { CustomColors( content = Color.Unspecified, component = Color.Unspecified, background = emptyList() ) } val LocalCustomTypography = staticCompositionLocalOf { CustomTypography( body = TextStyle.Default, title = TextStyle.Default ) } val LocalCustomElevation = staticCompositionLocalOf { CustomElevation( default = Dp.Unspecified, pressed = Dp.Unspecified ) } @Composable fun CustomTheme( /* ... */ content: @Composable () -> Unit ) { val customColors = CustomColors( content = Color(0xFFDD0D3C), component = Color(0xFFC20029), background = listOf(Color.White, Color(0xFFF8BBD0)) ) val customTypography = CustomTypography( body = TextStyle(fontSize = 16.sp), title = TextStyle(fontSize = 32.sp) ) val customElevation = CustomElevation( default = 4.dp, pressed = 8.dp ) CompositionLocalProvider( LocalCustomColors provides customColors, LocalCustomTypography provides customTypography, LocalCustomElevation provides customElevation, content = content ) } // Use with eg. CustomTheme.elevation.small object CustomTheme { val colors: CustomColors @Composable get() = LocalCustomColors.current val typography: CustomTypography @Composable get() = LocalCustomTypography.current val elevation: CustomElevation @Composable get() = LocalCustomElevation.current }
Material bileşenlerini kullanma
MaterialTheme
olmadığında, materyal bileşenleri olduğu gibi kullanıldığında istenmeyen materyal rengi, türü ve şekli değerleri ile gösterge davranışı ortaya çıkar.
Bileşenlerde özel değerler kullanmak istiyorsanız bunları kendi composable işlevlerinize sarmalayın, ilgili sistem için değerleri doğrudan ayarlayın ve diğer öğeleri, kapsayıcı composable'a parametre olarak gösterin.
Özel temanızdan ayarladığınız değerlere erişmenizi öneririz.
Alternatif olarak, temanızda Color
, TextStyle
, Shape
veya başka sistemler sağlanmıyorsa bunları kodla sabitleyebilirsiniz.
@Composable fun CustomButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( containerColor = CustomTheme.colors.component, contentColor = CustomTheme.colors.content, disabledContainerColor = CustomTheme.colors.content .copy(alpha = 0.12f) .compositeOver(CustomTheme.colors.component), disabledContentColor = CustomTheme.colors.content .copy(alpha = 0.38f) ), shape = ButtonShape, elevation = ButtonDefaults.elevatedButtonElevation( defaultElevation = CustomTheme.elevation.default, pressedElevation = CustomTheme.elevation.pressed /* disabledElevation = 0.dp */ ), onClick = onClick, modifier = modifier, content = { ProvideTextStyle( value = CustomTheme.typography.body ) { content() } } ) } val ButtonShape = RoundedCornerShape(percent = 50)
Eğimlendirmeleri temsil etmek için List<Color>
gibi yeni sınıf türleri tanıttıysanız bileşenleri sarmalamak yerine sıfırdan uygulamak daha iyi olabilir. Örneğin, Jetsnack örneğindeki JetsnackButton
öğesine göz atın.
Sizin için önerilenler
- Not: JavaScript kapalıyken bağlantı metni gösterilir
- Oluşturma'da Materyal Tasarım 3
- Oluştur'da 2. Malzeme'den 3. Malzeme'ye geçme
- Oluştur'daki bir temanın anatomisi