हमारा सुझाव है कि आप Material डिज़ाइन सिस्टम का इस्तेमाल करें. Jetpack Compose में Material का इंप्लीमेंटेशन शामिल है. हालांकि, आपको इसका इस्तेमाल करने के लिए मजबूर नहीं किया जाता. Material को पूरी तरह से सार्वजनिक एपीआई पर बनाया गया है. इसलिए, इसी तरह से अपना डिज़ाइन सिस्टम बनाया जा सकता है.
इसके लिए, कई तरीके अपनाए जा सकते हैं:
- थीमिंग की अन्य वैल्यू का इस्तेमाल करके
MaterialTheme
को बढ़ाना - एक या उससे ज़्यादा Material सिस्टम —
Colors
,Typography
याShapes
— को कस्टम तरीके से लागू किए गए सिस्टम से बदलना. हालांकि, ऐसा करते समय अन्य सिस्टम को बनाए रखना होगा MaterialTheme
को बदलने के लिए, पूरी तरह से कस्टम डिज़ाइन सिस्टम लागू करना
ऐसा भी हो सकता है कि आपको कस्टम डिज़ाइन सिस्टम के साथ Material कॉम्पोनेंट का इस्तेमाल जारी रखना हो. ऐसा किया जा सकता है. हालांकि, आपको कुछ बातों का ध्यान रखना होगा, ताकि आपके चुने गए तरीके के हिसाब से काम हो सके.
MaterialTheme
और कस्टम डिज़ाइन सिस्टम में इस्तेमाल होने वाले लोअर-लेवल कंस्ट्रक्ट और एपीआई के बारे में ज़्यादा जानने के लिए, Compose में थीम की संरचना गाइड देखें.
मटीरियल थीम को बढ़ाना
Compose Material, Material Theming के हिसाब से काम करता है, ताकि Material के दिशा-निर्देशों का पालन करना आसान और टाइप-सेफ़ हो. हालांकि, रंग, टाइपोग्राफ़ी, और आकार के सेट को अतिरिक्त वैल्यू के साथ बढ़ाया जा सकता है.
एक्सटेंशन प्रॉपर्टी जोड़ने का सबसे आसान तरीका यह है:
// 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)
इससे MaterialTheme
के इस्तेमाल से जुड़े एपीआई के साथ एक जैसा अनुभव मिलता है. Compose में पहले से तय किए गए इस तरह के उदाहरण में surfaceColorAtElevation
शामिल है. यह एलिवेशन के आधार पर, इस्तेमाल किए जाने वाले सर्फ़ेस के रंग का पता लगाता है.
एक और तरीका यह है कि एक एक्सटेंडेड थीम तय की जाए, जो MaterialTheme
और उसकी वैल्यू को "रैप" करती है.
मान लें कि आपको दो और रंग जोड़ने हैं — caution
और onCaution
. caution
रंग का इस्तेमाल उन कार्रवाइयों के लिए किया जाता है जो कुछ हद तक खतरनाक होती हैं. साथ ही, आपको मौजूदा Material रंग भी रखने हैं:
@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 }
यह MaterialTheme
के इस्तेमाल से जुड़े एपीआई की तरह ही है. यह कई थीम के साथ भी काम करता है, क्योंकि ExtendedTheme
को MaterialTheme
की तरह ही नेस्ट किया जा सकता है.
मटीरियल कॉम्पोनेंट का इस्तेमाल करना
मटेरियल थीमिंग को बढ़ाने पर, मौजूदा MaterialTheme
वैल्यू बनी रहती हैं और मटेरियल कॉम्पोनेंट में अब भी डिफ़ॉल्ट वैल्यू मौजूद होती हैं.
अगर आपको कॉम्पोनेंट में एक्सटेंड की गई वैल्यू का इस्तेमाल करना है, तो उन्हें अपने कंपोज़ेबल फ़ंक्शन में रैप करें. इसके बाद, उन वैल्यू को सीधे तौर पर सेट करें जिनमें आपको बदलाव करना है. साथ ही, अन्य वैल्यू को कंपोज़ेबल फ़ंक्शन में पैरामीटर के तौर पर दिखाएं:
@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 ) }
इसके बाद, आपको Button
की जगह ExtendedButton
का इस्तेमाल करना होगा.
@Composable fun ExtendedApp() { ExtendedTheme { /*...*/ ExtendedButton(onClick = { /* ... */ }) { /* ... */ } } }
मटेरियल सब-सिस्टम को बदलना
ऐसा हो सकता है कि आपको Material Theming को बढ़ाने के बजाय, एक या उससे ज़्यादा सिस्टम — Colors
, Typography
या Shapes
— को कस्टम थीम के साथ बदलना हो. हालांकि, ऐसा करते समय आपको अन्य सिस्टम को बनाए रखना होगा.
मान लें कि आपको रंग सिस्टम को बनाए रखते हुए, टाइप और शेप सिस्टम को बदलना है:
@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 }
मटीरियल कॉम्पोनेंट का इस्तेमाल करना
जब MaterialTheme
के एक या उससे ज़्यादा सिस्टम बदल दिए जाते हैं, तो Material
components का इस्तेमाल करने से, Material के रंग, टाइप या आकार की अवांछित वैल्यू मिल सकती हैं.
अगर आपको कॉम्पोनेंट में बदली गई वैल्यू का इस्तेमाल करना है, तो उन्हें अपने कंपोज़ेबल फ़ंक्शन में रैप करें. साथ ही, सीधे तौर पर संबंधित सिस्टम के लिए वैल्यू सेट करें. इसके अलावा, अन्य वैल्यू को कंपोज़ेबल फ़ंक्शन में शामिल करने के लिए, उन्हें पैरामीटर के तौर पर दिखाएं.
@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() } } ) }
इसके बाद, आपको Button
की जगह ReplacementButton
का इस्तेमाल करना होगा.
@Composable fun ReplacementApp() { ReplacementTheme { /*...*/ ReplacementButton(onClick = { /* ... */ }) { /* ... */ } } }
पूरी तरह से कस्टम डिज़ाइन सिस्टम लागू करना
ऐसा हो सकता है कि आपको मटीरियल थीमिंग को पूरी तरह से कस्टम डिज़ाइन सिस्टम से बदलना हो.
मान लें कि MaterialTheme
ये सिस्टम उपलब्ध कराता है:
Colors
,Typography
, औरShapes
: मटीरियल थीमिंग सिस्टमTextSelectionColors
:Text
औरTextField
की मदद से टेक्स्ट चुनने के लिए इस्तेमाल किए गए रंगRipple
औरRippleTheme
:Indication
का मटीरियल इंप्लिमेंटेशन
अगर आपको Material कॉम्पोनेंट का इस्तेमाल जारी रखना है, तो आपको अपनी कस्टम थीम या थीम में इन सिस्टम में से कुछ को बदलना होगा. इसके अलावा, आपको अपने कॉम्पोनेंट में सिस्टम को मैनेज करना होगा, ताकि अनचाही गतिविधि से बचा जा सके.
हालांकि, डिज़ाइन सिस्टम सिर्फ़ उन कॉन्सेप्ट पर आधारित नहीं होते जिन पर Material निर्भर करता है. मौजूदा सिस्टम में बदलाव किया जा सकता है. साथ ही, नई क्लास और टाइप के साथ पूरी तरह से नए सिस्टम जोड़े जा सकते हैं. इससे अन्य कॉन्सेप्ट को थीम के साथ काम करने लायक बनाया जा सकता है.
नीचे दिए गए कोड में, हमने कस्टम कलर सिस्टम को मॉडल किया है. इसमें ग्रेडिएंट (List<Color>
) शामिल हैं. साथ ही, इसमें टाइप सिस्टम और नया एलिवेशन सिस्टम शामिल किया गया है. इसके अलावा, MaterialTheme
की ओर से उपलब्ध कराए गए अन्य सिस्टम को शामिल नहीं किया गया है:
@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 }
मटीरियल कॉम्पोनेंट का इस्तेमाल करना
MaterialTheme
मौजूद न होने पर, Material कॉम्पोनेंट का इस्तेमाल करने से, Material के रंग, टाइप, और आकार की अनचाही वैल्यू मिलेंगी. साथ ही, इंडिकेशन के तौर-तरीके में भी बदलाव होगा.
अगर आपको कॉम्पोनेंट में कस्टम वैल्यू का इस्तेमाल करना है, तो उन्हें अपने कंपोज़ेबल फ़ंक्शन में रैप करें. साथ ही, सीधे तौर पर सिस्टम के लिए काम की वैल्यू सेट करें. इसके अलावा, अन्य वैल्यू को कंपोज़ेबल कॉम्पोनेंट के पैरामीटर के तौर पर दिखाएं.
हमारा सुझाव है कि आपने कस्टम थीम में जो वैल्यू सेट की हैं उन्हें ऐक्सेस करें.
इसके अलावा, अगर आपकी थीम में Color
, TextStyle
, Shape
या अन्य सिस्टम उपलब्ध नहीं हैं, तो उन्हें हार्डकोड किया जा सकता है.
@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)
अगर आपने नए क्लास टाइप जोड़े हैं, जैसे कि List<Color>
, तो रैप करने के बजाय कॉम्पोनेंट को शुरू से लागू करना बेहतर हो सकता है. उदाहरण के लिए, Jetsnack के सैंपल में मौजूद
JetsnackButton
देखें.
आपके लिए सुझाव
- ध्यान दें: JavaScript बंद होने पर लिंक टेक्स्ट दिखता है
- Compose में Material Design 3
- Compose में Material 2 से Material 3 पर माइग्रेट करना
- Compose में थीम के कॉम्पोनेंट