Önerdiğimiz tasarım sistemimiz Materyal'dir ve Jetpack Compose bir Materyal uygulaması sunsa da bu özelliği kullanmak zorunda kalmazsınız. Materyal tümüyle herkese açık API'ler üzerinde derlendiğinden, aynı şekilde kendi tasarım sisteminizi de oluşturabilirsiniz.
Bu konuda uygulayabileceğiniz çeşitli yaklaşımlar vardır:
- Ek tema değerleriyle
MaterialTheme
kapsamını genişletme - Bir veya daha fazla Materyal sistemi (
Colors
,Typography
veyaShapes
) özel uygulamalarla değiştirirken diğerlerini değiştirme MaterialTheme
öğesinin yerini alacak tamamen özel bir tasarım sistemi uygulama
Ayrıca, Malzeme bileşenlerini özel bir tasarım sistemiyle kullanmaya devam edebilirsiniz. Bunu yapmak mümkün olsa da benimsediğiniz yaklaşıma uygun olması 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'ler hakkında daha fazla bilgi edinmek için Compose'da bir temanın anatomisi kılavuzuna göz atın.
Materyal Temasını Genişletme
Oluşturma Materyali, Materyal yönergelerini izlemenin basit ve güvenli olması için Materyal Tema'yı yakından modeller. Ancak renk, tipografi ve şekil gruplarını ek değerlerle genişletmek mümkündür.
En basit yaklaşım uzantı özellikleri eklemektir:
// Use with MaterialTheme.colors.snackbarAction val Colors.snackbarAction: Color get() = if (isLight) 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'un kendisi tarafından tanımlanan bunun bir örneği, Colors.isLight
'ye bağlı olarak primary
ile surface
arasında bir proxy işlevi gören primarySurface
örneğidir.
Diğer bir yaklaşım da MaterialTheme
öğesini ve değerlerini "sarlayan" genişletilmiş bir tema tanımlamaktır.
Mevcut Malzeme renklerini korurken tertiary
ve onTertiary
şeklinde iki renk daha eklemek istediğinizi varsayalım:
@Immutable data class ExtendedColors( val tertiary: Color, val onTertiary: Color ) val LocalExtendedColors = staticCompositionLocalOf { ExtendedColors( tertiary = Color.Unspecified, onTertiary = Color.Unspecified ) } @Composable fun ExtendedTheme( /* ... */ content: @Composable () -> Unit ) { val extendedColors = ExtendedColors( tertiary = Color(0xFFA8EFF0), onTertiary = Color(0xFF002021) ) CompositionLocalProvider(LocalExtendedColors provides extendedColors) { MaterialTheme( /* colors = ..., typography = ..., shapes = ... */ content = content ) } } // Use with eg. ExtendedTheme.colors.tertiary 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 çok temayı da destekler.
Material bileşenlerini kullanma
Materyal Teması genişletilirken mevcut MaterialTheme
değerleri korunur ve Malzeme bileşenlerinin varsayılan değerleri hâlâ makuldür.
Bileşenlerde genişletilmiş değerler kullanmak istiyorsanız bunları kendi composable işlevlerinizde sarmalayın, değiştirmek istediğiniz değerleri doğrudan ayarlayın ve diğerlerini içeren composable'a parametre olarak maruz bırakın:
@Composable fun ExtendedButton( onClick: () -> Unit, modifier: Modifier = Modifier, content: @Composable RowScope.() -> Unit ) { Button( colors = ButtonDefaults.buttonColors( containerColor = ExtendedTheme.colors.tertiary, contentColor = ExtendedTheme.colors.onTertiary /* Other colors use values from MaterialTheme */ ), onClick = onClick, modifier = modifier, content = content ) }
Bu durumda Button
kullanımlarını uygun durumlarda ExtendedButton
ile değiştirirsiniz.
@Composable fun ExtendedApp() { ExtendedTheme { /*...*/ ExtendedButton(onClick = { /* ... */ }) { /* ... */ } } }
Malzeme sistemlerini değiştirme
Materyal Teması'nı genişletmek yerine, bir veya daha fazla sistemi (Colors
, Typography
veya Shapes
) özel bir uygulamayla değiştirirken diğerlerini 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 }
Material bileşenlerini kullanma
Bir veya daha fazla MaterialTheme
sistemi değiştirildiğinde, Malzeme bileşenlerini olduğu gibi kullanmak istenmeyen Malzeme renk, tür veya şekil değerlerine neden olabilir.
Bileşenlerde değiştirme değerleri kullanmak isterseniz bunları kendi composable işlevlerinizde sarmalayın, ilgili sistemin değerlerini doğrudan ayarlayın ve diğerlerini de içeren composable'a parametre olarak gösterin.
@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() } } ) }
Bu durumda Button
kullanımlarını uygun durumlarda ReplacementButton
ile değiştirirsiniz.
@Composable fun ReplacementApp() { ReplacementTheme { /*...*/ ReplacementButton(onClick = { /* ... */ }) { /* ... */ } } }
Tamamen özel bir tasarım sistemi uygulamak
Materyal Teması'nı tamamen özel bir tasarım sistemiyle değiştirmek isteyebilirsiniz.
MaterialTheme
ürününün aşağıdaki sistemleri sağladığını göz önünde bulundurun:
Colors
,Typography
veShapes
: Materyal Tema oluşturma sistemleriContentAlpha
:Text
veIcon
ürünlerinde vurguyu aktarmak için opaklık seviyeleriTextSelectionColors
:Text
veTextField
tarafından metin seçiminde kullanılan renklerRipple
veRippleTheme
:Indication
öğesinin materyal uygulaması
Materyal bileşenlerini kullanmaya devam etmek istiyorsanız istenmeyen davranışlardan kaçınmak için özel temanızda veya temalarınızda bu sistemlerden bazılarını değiştirmeniz veya bileşenlerinizdeki sistemleri işlemeniz gerekir.
Ancak tasarım sistemleri, Materyal'in 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 yenilerini kullanıma sunabilirsiniz.
Aşağıdaki kodda, gradyanlar (List<Color>
) içeren özel bir renk sistemini modeller, bir tür sistemi ekler, yeni bir yükseklik sistemi ekler ve MaterialTheme
tarafından sağlanan diğer sistemleri hariç tutarız:
@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
yoksa, Malzeme bileşenlerini olduğu gibi kullanmak istenmeyen Malzeme rengi, türü, şekli değerleri ve gösterge davranışlarına neden olur.
Bileşenlerde özel değerler kullanmak istiyorsanız bunları kendi composable işlevlerinizde sarmalayın, ilgili sistem için değerleri doğrudan ayarlayın ve diğerlerini parametre olarak içeren composable'a gösterin.
Özel temanızdan ayarladığınız değerlere erişmenizi öneririz. Alternatif olarak, temanız Color
, TextStyle
, Shape
veya diğer sistemleri sağlamıyorsa bunları sabit bir şekilde kodlayabilirsiniz.
@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 = ContentAlpha.disabled) ), 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)
Renk geçişlerini göstermek için List<Color>
gibi yeni sınıf türleri kullanıma sunduysanız bileşenleri sarmalamak yerine sıfırdan uygulamak daha iyi olabilir. Örneğin, Jetsnack örneğinden JetsnackButton
adresine bakalım.
Sizin için önerilenler
- Not: Bağlantı metni JavaScript kapalıyken görüntülenir
- Oluşturma işleminde Materyal Tasarım 2
- Oluşturma bölümünde Materyal 2'den Materyal 3'e geçiş
- Compose'da bir temanın anatomisi