Jetpack Compose में आर्किटेक्चर की लेयर जोड़ना

इस पेज पर, Jetpack Compose को बनाने वाली आर्किटेक्चर लेयर के बारे में खास जानकारी दी गई है. साथ ही, इस डिज़ाइन के मुख्य सिद्धांतों के बारे में भी बताया गया है.

Jetpack Compose, एक सिंगल मोनोलिथिक प्रोजेक्ट नहीं है. इसे कई मॉड्यूल से बनाया गया है. इन मॉड्यूल को एक साथ असेंबल करके, पूरा स्टैक बनाया जाता है. Jetpack Compose बनाने वाले अलग-अलग मॉड्यूल के बारे में जानने से, आपको ये काम करने में मदद मिलती है:

  • अपने ऐप्लिकेशन या लाइब्रेरी को बनाने के लिए, ऐब्स्ट्रैक्शन के सही लेवल का इस्तेमाल करना
  • यह समझना कि ज़्यादा कंट्रोल या पसंद के मुताबिक बनाने के लिए, आपको कब निचले लेवल पर ‘ड्रॉप डाउन’ करना चाहिए
  • डिपेंडेंसी कम करें

परतें

Jetpack Compose की मुख्य लेयर ये हैं:

पहली इमेज. Jetpack Compose की मुख्य लेयर.

हर लेयर, निचले लेवल पर बनाई जाती है. इसमें फ़ंक्शन को मिलाकर, उच्च लेवल के कॉम्पोनेंट बनाए जाते हैं. हर लेयर, निचली लेयर के सार्वजनिक एपीआई पर आधारित होती है. इससे मॉड्यूल की सीमाओं की पुष्टि की जा सकती है. साथ ही, अगर आपको किसी लेयर को बदलना है, तो ऐसा किया जा सकता है. आइए, इन लेयर को नीचे से ऊपर की ओर देखते हैं.

रनटाइम
इस मॉड्यूल में, Compose रनटाइम की बुनियादी बातों के बारे में बताया गया है. जैसे, remember, mutableStateOf, @Composable एनोटेशन, और SideEffect. अगर आपको सिर्फ़ Compose की ट्री मैनेजमेंट की क्षमताओं की ज़रूरत है, न कि इसके यूज़र इंटरफ़ेस (यूआई) की, तो इस लेयर पर सीधे तौर पर बनाया जा सकता है.
UI
यूज़र इंटरफ़ेस (यूआई) लेयर में कई मॉड्यूल होते हैं ( ui-text, ui-graphics, ui-tooling वगैरह). इन मॉड्यूल में यूज़र इंटरफ़ेस (यूआई) टूलकिट की बुनियादी बातों को लागू किया जाता है. जैसे, LayoutNode, Modifier, इनपुट हैंडलर, कस्टम लेआउट, और ड्रॉइंग. अगर आपको सिर्फ़ यूज़र इंटरफ़ेस (यूआई) टूलकिट के बुनियादी सिद्धांतों की ज़रूरत है, तो इस लेयर का इस्तेमाल किया जा सकता है.
Foundation
यह मॉड्यूल, Compose यूज़र इंटरफ़ेस (यूआई) के लिए डिज़ाइन सिस्टम से जुड़े बिल्डिंग ब्लॉक उपलब्ध कराता है. जैसे, Row और Column, LazyColumn, खास तरह के जेस्चर की पहचान करना वगैरह. अपना डिज़ाइन सिस्टम बनाने के लिए, फ़ाउंडेशन लेयर का इस्तेमाल किया जा सकता है.
सामग्री
यह मॉड्यूल, Compose यूज़र इंटरफ़ेस (यूआई) के लिए, मटीरियल डिज़ाइन सिस्टम को लागू करता है. इसमें थीमिंग सिस्टम, स्टाइल वाले कॉम्पोनेंट, रिपल इंडिकेशन, और आइकॉन शामिल हैं. अपने ऐप्लिकेशन में Material Design का इस्तेमाल करते समय, इस लेयर को बनाएं.

डिज़ाइन से जुड़े सिद्धांत

Jetpack Compose का मुख्य सिद्धांत यह है कि यह छोटे-छोटे और खास फ़ंक्शन उपलब्ध कराता है. इन्हें एक साथ असेंबल (या कंपोज़) किया जा सकता है. इसके बजाय, यह कुछ बड़े कॉम्पोनेंट उपलब्ध कराता है. इस तरीके के कई फ़ायदे हैं.

कंट्रोल

बड़े कॉम्पोनेंट, आपके लिए ज़्यादा काम करते हैं. हालांकि, इससे आपको सीधे तौर पर कंट्रोल करने की सुविधा कम मिलती है. अगर आपको ज़्यादा कंट्रोल चाहिए, तो "ड्रॉप-डाउन" करके, निचले लेवल के कॉम्पोनेंट का इस्तेमाल करें.

उदाहरण के लिए, अगर आपको किसी कॉम्पोनेंट के रंग में ऐनिमेशन जोड़ना है, तो animateColorAsState एपीआई का इस्तेमाल करें:

val color = animateColorAsState(if (condition) Color.Green else Color.Red)

हालांकि, अगर आपको कॉम्पोनेंट को हमेशा ग्रे रंग में दिखाना है, तो इस एपीआई का इस्तेमाल नहीं किया जा सकता. इसके बजाय, नीचे दिए गए Animatable एपीआई का इस्तेमाल किया जा सकता है:

val color = remember { Animatable(Color.Gray) }
LaunchedEffect(condition) {
    color.animateTo(if (condition) Color.Green else Color.Red)
}

ज़्यादा लेवल वाला animateColorAsState एपीआई, कम लेवल वाले Animatable एपीआई पर ही बनाया गया है. लोअर लेवल एपीआई का इस्तेमाल करना ज़्यादा मुश्किल है, लेकिन इससे ज़्यादा कंट्रोल मिलता है. अपनी ज़रूरत के हिसाब से, ऐब्स्ट्रैक्शन का लेवल चुनें.

पसंद के मुताबिक बनाएं

छोटे बिल्डिंग ब्लॉक से बड़े कॉम्पोनेंट को असेंबल करने से, ज़रूरत पड़ने पर कॉम्पोनेंट को पसंद के मुताबिक बनाना बहुत आसान हो जाता है. उदाहरण के लिए, मटीरियल लेयर की ओर से उपलब्ध कराए गए Button को लागू करने का तरीका देखें:

@Composable
fun Button(
    // …
    content: @Composable RowScope.() -> Unit
) {
    Surface(/* … */) {
        CompositionLocalProvider(/* … */) { // set LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                Row(
                    // …
                    content = content
                )
            }
        }
    }
}

Button को चार कॉम्पोनेंट से बनाया जाता है:

  1. यह एक मटीरियल है Surface जो बैकग्राउंड, शेप, क्लिक हैंडलिंग वगैरह की जानकारी देता है.

  2. A CompositionLocalProvider जो बटन के चालू या बंद होने पर, कॉन्टेंट के ऐल्फ़ा को बदलता है

  3. A ProvideTextStyle टेक्स्ट के लिए डिफ़ॉल्ट स्टाइल सेट करता है

  4. Row, बटन के कॉन्टेंट के लिए लेआउट की डिफ़ॉल्ट नीति तय करता है

हमने स्ट्रक्चर को ज़्यादा साफ़ तौर पर दिखाने के लिए, कुछ पैरामीटर और टिप्पणियां हटा दी हैं. हालांकि, पूरा कॉम्पोनेंट सिर्फ़ 40 लाइनों का कोड है, क्योंकि यह बटन को लागू करने के लिए, इन चार कॉम्पोनेंट को असेंबल करता है. Button जैसे कॉम्पोनेंट, यह तय करते हैं कि वे कौनसे पैरामीटर दिखाएंगे. ऐसा इसलिए, ताकि सामान्य कस्टम सेटिंग को चालू करने और पैरामीटर की संख्या को कम करने के बीच संतुलन बना रहे. इससे कॉम्पोनेंट को इस्तेमाल करना आसान हो जाता है. उदाहरण के लिए, मटीरियल कॉम्पोनेंट में, Material Design सिस्टम में बताई गई सेटिंग को पसंद के मुताबिक बनाने का विकल्प मिलता है. इससे, Material Design के सिद्धांतों को आसानी से फ़ॉलो किया जा सकता है.

हालांकि, अगर आपको किसी कॉम्पोनेंट के पैरामीटर से ज़्यादा बदलाव करने हैं, तो एक लेवल "ड्रॉप डाउन" करके कॉम्पोनेंट को फ़ोर्क किया जा सकता है. उदाहरण के लिए, Material Design में बताया गया है कि बटन का बैकग्राउंड गहरे रंग का होना चाहिए. अगर आपको ग्रेडिएंट बैकग्राउंड चाहिए, तो यह विकल्प Button पैरामीटर के साथ काम नहीं करता. इस मामले में, मटीरियल Button के लागू करने के तरीके को रेफ़रंस के तौर पर इस्तेमाल किया जा सकता है. साथ ही, अपना कॉम्पोनेंट बनाया जा सकता है:

@Composable
fun GradientButton(
    // …
    background: List<Color>,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        // …
        modifier = modifier
            .clickable(onClick = {})
            .background(
                Brush.horizontalGradient(background)
            )
    ) {
        CompositionLocalProvider(/* … */) { // set material LocalContentAlpha
            ProvideTextStyle(MaterialTheme.typography.button) {
                content()
            }
        }
    }
}

ऊपर दिए गए उदाहरण में, Material लेयर के कॉम्पोनेंट का इस्तेमाल किया गया है. जैसे, Material के मौजूदा कॉन्टेंट का ऐल्फ़ा और मौजूदा टेक्स्ट स्टाइल के कॉन्सेप्ट. हालांकि, यह मटीरियल Surface को Row से बदलता है और इसे स्टाइल करता है, ताकि यह आपकी पसंद के मुताबिक दिखे.

अगर आपको मटीरियल कॉन्सेप्ट का इस्तेमाल नहीं करना है, तो फ़ाउंडेशन लेयर के कॉम्पोनेंट का इस्तेमाल किया जा सकता है. उदाहरण के लिए, अगर आपको अपना कस्टम डिज़ाइन सिस्टम बनाना है, तो फ़ाउंडेशन लेयर के कॉम्पोनेंट का इस्तेमाल करें:

@Composable
fun BespokeButton(
    // …
    backgroundColor: Color,
    modifier: Modifier = Modifier,
    content: @Composable RowScope.() -> Unit
) {
    Row(
        // …
        modifier = modifier
            .clickable(onClick = {})
            .background(backgroundColor)
    ) {
        // No Material components used
        content()
    }
}

Jetpack Compose, सबसे ऊपर वाले लेवल के कॉम्पोनेंट के लिए सबसे आसान नाम रिज़र्व करता है. उदाहरण के लिए, androidx.compose.material.Text को androidx.compose.foundation.text.BasicText के आधार पर बनाया गया है. इससे आपको ज़्यादा डिस्कवर किए जाने वाले नाम के साथ अपना खुद का लागू करने का तरीका उपलब्ध कराने में मदद मिलती है. ऐसा तब होता है, जब आपको ज़्यादा लेवल बदलने हों.

सही ऐब्स्ट्रैक्शन चुनना

Compose में लेयर वाले, दोबारा इस्तेमाल किए जा सकने वाले कॉम्पोनेंट बनाने के सिद्धांत का मतलब है कि आपको हमेशा निचले लेवल के बिल्डिंग ब्लॉक का इस्तेमाल नहीं करना चाहिए. ऊंचे लेवल के कई कॉम्पोनेंट, न सिर्फ़ ज़्यादा सुविधाएं देते हैं, बल्कि अक्सर सुलभता जैसी सबसे सही प्रक्रियाओं को लागू करते हैं.

उदाहरण के लिए, अगर आपको अपने कस्टम कॉम्पोनेंट में जेस्चर सपोर्ट जोड़ना है, तो Modifier.pointerInput का इस्तेमाल करके इसे शुरू से बनाया जा सकता है. हालांकि, इसके ऊपर अन्य, ज़्यादा लेवल के कॉम्पोनेंट बनाए गए हैं. ये कॉम्पोनेंट, बेहतर शुरुआती पॉइंट दे सकते हैं. उदाहरण के लिए, Modifier.draggable, Modifier.scrollable या Modifier.swipeable.

नियम के तौर पर, सबसे ऊपरी लेवल वाले कॉम्पोनेंट का इस्तेमाल करें. इससे आपको सबसे सही तरीकों का फ़ायदा पाने के लिए ज़रूरी फ़ंक्शन मिलते हैं.

ज़्यादा जानें

कस्टम डिज़ाइन सिस्टम बनाने का उदाहरण देखने के लिए, Jetsnack का सैंपल देखें.