कंस्ट्रेंट और मॉडिफ़ायर ऑर्डर

Compose में, एक कंपोज़ेबल के लुक और फ़ील को बदलने के लिए, कई मॉडिफ़ायर को एक साथ जोड़ा जा सकता है. मॉडिफ़ायर की इन चेन से, कंपोज़ेबल को पास की गई बाधाओं पर असर पड़ सकता है. ये बाधाएं, चौड़ाई और ऊंचाई की सीमाएं तय करती हैं.

इस पेज पर बताया गया है कि चेन किए गए मॉडिफ़ायर, कंस्ट्रेंट पर कैसे असर डालते हैं. साथ ही, कंपोज़ेबल के मेज़रमेंट और प्लेसमेंट पर कैसे असर डालते हैं.

यूज़र इंटरफ़ेस (यूआई) ट्री में मॉडिफ़ायर

मॉडिफ़ायर एक-दूसरे को कैसे प्रभावित करते हैं, यह समझने के लिए यह देखना मददगार होता है कि वे कंपोज़िशन फ़ेज़ के दौरान जनरेट होने वाले यूज़र इंटरफ़ेस (यूआई) ट्री में कैसे दिखते हैं. ज़्यादा जानकारी के लिए, कंपोज़िशन सेक्शन देखें.

यूज़र इंटरफ़ेस (यूआई) ट्री में, लेआउट नोड के लिए रैपर नोड के तौर पर मॉडिफ़ायर देखे जा सकते हैं:

कंपोज़ेबल और मॉडिफ़ायर के लिए कोड और यूज़र इंटरफ़ेस (यूआई) ट्री के तौर पर उनका विज़ुअल प्रज़ेंटेशन.
पहली इमेज. यूज़र इंटरफ़ेस (यूआई) ट्री में लेआउट नोड को रैप करने वाले मॉडिफ़ायर.

किसी कंपोज़ेबल में एक से ज़्यादा मॉडिफ़ायर जोड़ने पर, मॉडिफ़ायर की एक चेन बन जाती है. एक से ज़्यादा मॉडिफ़ायर को एक साथ इस्तेमाल करने पर, हर मॉडिफ़ायर नोड, चेन के बाकी नोड और लेआउट नोड को रैप करता है. उदाहरण के लिए, जब clip और size मॉडिफ़ायर को एक साथ इस्तेमाल किया जाता है, तब clip मॉडिफ़ायर नोड, size मॉडिफ़ायर नोड को रैप करता है. इसके बाद, यह Image लेआउट नोड को रैप करता है.

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

जैसा कि दूसरे डायग्राम में दिखाया गया है, Image और Text कंपोज़ेबल को लागू करने के लिए, एक लेआउट नोड को रैप करने वाले मॉडिफ़ायर की चेन का इस्तेमाल किया जाता है.

Row और Column के लेआउट नोड, यह बताते हैं कि उनके चाइल्ड नोड को कैसे लेआउट करना है.

पहले वाला ट्री स्ट्रक्चर, लेकिन अब हर नोड सिर्फ़ एक सामान्य लेआउट है. इसमें कई मॉडिफ़ायर रैपिंग नोड मौजूद हैं.
दूसरी इमेज. यह पहली इमेज में दिखाए गए ट्री स्ट्रक्चर जैसा ही है. हालांकि, इसमें यूज़र इंटरफ़ेस (यूआई) ट्री में कंपोज़ेबल को मॉडिफ़ायर की चेन के तौर पर दिखाया गया है.

खास जानकारी पाने के लिए:

  • मॉडिफ़ायर, किसी एक मॉडिफ़ायर या लेआउट नोड को रैप करते हैं.
  • लेआउट नोड, कई चाइल्ड नोड को लेआउट कर सकते हैं.

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

लेआउट फ़ेज़ में कंस्ट्रेंट

लेआउट फ़ेज़ में, हर लेआउट नोड की चौड़ाई, ऊंचाई, और x, y कोऑर्डिनेट का पता लगाने के लिए, तीन चरणों वाला एल्गोरिदम इस्तेमाल किया जाता है:

  1. बच्चों का मेज़रमेंट करना: अगर किसी नोड में चाइल्ड नोड मौजूद हैं, तो वह उनका मेज़रमेंट करता है.
  2. अपना साइज़ तय करना: इन मेज़रमेंट के आधार पर, कोई नोड अपना साइज़ खुद तय करता है.
  3. बच्चों को जगह देना: हर चाइल्ड नोड को, नोड की अपनी पोज़िशन के हिसाब से रखा जाता है.

Constraints से, एल्गोरिदम के पहले दो चरणों के दौरान नोड के सही साइज़ का पता लगाने में मदद मिलती है. बाधाएं, किसी नोड की चौड़ाई और ऊंचाई के लिए कम से कम और ज़्यादा से ज़्यादा सीमाएं तय करती हैं. जब नोड अपने साइज़ का फ़ैसला करता है, तो उसका मेज़र किया गया साइज़, साइज़ की इस सीमा के अंदर होना चाहिए.

अलग-अलग तरह की पाबंदियां

पाबंदी इनमें से कोई एक हो सकती है:

  • सीमा तय है: नोड की चौड़ाई और ऊंचाई की ज़्यादा से ज़्यादा और कम से कम सीमा तय होती है.
कंटेनर में अलग-अलग साइज़ की बाउंडेड कंस्ट्रेंट.
तीसरी इमेज. सीमा से जुड़ी पाबंदियां.
  • अनबाउंडेड: नोड का साइज़ तय नहीं होता. ज़्यादा से ज़्यादा चौड़ाई और ऊंचाई की सीमाएं, इनफ़िनिटी पर सेट होती हैं.
अनबाउंड कंस्ट्रेंट, जिनकी चौड़ाई और ऊंचाई को इनफ़िनिटी पर सेट किया गया है. कंटेनर की सीमाओं से बाहर की जगह को भी शामिल किया गया है.
चौथी इमेज. अनबाउंड किए गए वैरिएबल के लिए, कोई भी सीमा नहीं होती.
  • सटीक: नोड को सटीक साइज़ की ज़रूरी शर्त का पालन करने के लिए कहा जाता है. कम से कम और ज़्यादा से ज़्यादा सीमा को एक ही वैल्यू पर सेट किया जाता है.
कंटेनर में मौजूद कॉन्टेंट के साइज़ से जुड़ी ज़रूरी शर्तों के मुताबिक सटीक सीमाएं.
पांचवीं इमेज. सटीक पाबंदियां.
  • कॉम्बिनेशन: नोड, पिछली पाबंदी के टाइप के कॉम्बिनेशन का पालन करता है. उदाहरण के लिए, किसी विज्ञापन की चौड़ाई को सीमित किया जा सकता है, जबकि उसकी ऊंचाई को असीमित रखा जा सकता है. इसके अलावा, विज्ञापन की चौड़ाई को सटीक तौर पर सेट किया जा सकता है, लेकिन उसकी ऊंचाई को सीमित किया जा सकता है.
दो कंटेनर, जिनमें बाउंडेड और अनबाउंडेड कंस्ट्रेंट के कॉम्बिनेशन और सटीक चौड़ाई और ऊंचाई दिखाई गई है.
छठी इमेज. बाउंडेड और अनबाउंडेड कंस्ट्रेंट के साथ-साथ चौड़ाई और लंबाई की सटीक वैल्यू के कॉम्बिनेशन.

अगले सेक्शन में बताया गया है कि ये पाबंदियां, पैरंट से चाइल्ड में कैसे पास की जाती हैं.

कॉन्स्ट्रेंट को पैरंट से चाइल्ड में कैसे पास किया जाता है

लेआउट फ़ेज़ में मौजूद सीमाएं में बताए गए एल्गोरिदम के पहले चरण के दौरान, यूज़र इंटरफ़ेस (यूआई) ट्री में सीमाओं को पैरंट से चाइल्ड में पास किया जाता है.

जब कोई पैरंट नोड अपने चाइल्ड नोड का साइज़ तय करता है, तो वह हर चाइल्ड नोड को ये सीमाएं उपलब्ध कराता है. इससे चाइल्ड नोड को पता चलता है कि उसे कितना बड़ा या छोटा होने की अनुमति है. इसके बाद, जब यह अपना साइज़ तय करता है, तो यह उन शर्तों का भी पालन करता है जो इसके माता-पिता ने पास की थीं.

बड़े लेवल पर, एल्गोरिदम इस तरह काम करता है:

  1. यूज़र इंटरफ़ेस (यूआई) ट्री में मौजूद रूट नोड, यह तय करता है कि उसे कितना साइज़ चाहिए. इसके लिए, वह अपने चाइल्ड नोड का साइज़ मेज़र करता है और पहली शर्त को अपने पहले चाइल्ड नोड को भेजता है.
  2. अगर चाइल्ड एक ऐसा मॉडिफ़ायर है जिससे मेज़रमेंट पर कोई असर नहीं पड़ता है, तो यह अगले मॉडिफ़ायर को कंस्ट्रेंट भेजता है. मॉडिफ़ायर की चेन में, शर्तों को उसी तरह से आगे बढ़ाया जाता है. ऐसा तब तक होता है, जब तक कि मेज़रमेंट पर असर डालने वाला कोई मॉडिफ़ायर नहीं मिल जाता. इसके बाद, सीमाओं का साइज़ बदल दिया जाता है.
  3. जब कोई ऐसा नोड मिलता है जिसके कोई चाइल्ड नोड नहीं होते (इसे "लीफ़ नोड" कहा जाता है), तो यह नोड, पास की गई सीमाओं के आधार पर अपना साइज़ तय करता है. इसके बाद, यह तय किए गए साइज़ को अपने पैरंट नोड को वापस भेज देता है.
  4. पैरंट, बच्चे के मेज़रमेंट के आधार पर अपनी सीमाओं को अडजस्ट करता है. इसके बाद, वह अडजस्ट की गई सीमाओं के साथ अपने अगले बच्चे को कॉल करता है.
  5. जब किसी पैरंट के सभी बच्चों का मेज़रमेंट हो जाता है, तो पैरंट नोड अपने साइज़ का फ़ैसला खुद करता है और इसकी जानकारी अपने पैरंट को देता है.
  6. इस तरह, पूरे ट्री को डेप्थ-फ़र्स्ट तरीके से ट्रैवर्स किया जाता है. आखिरकार, सभी नोड अपने साइज़ तय कर लेते हैं और मेज़रमेंट का चरण पूरा हो जाता है.

ज़्यादा जानकारी के लिए, Constraints and modifier order वीडियो देखें.

ऐसे मॉडिफ़ायर जिनका असर शर्तों पर पड़ता है

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

size मॉडिफ़ायर

size मॉडिफ़ायर, कॉन्टेंट के पसंदीदा साइज़ के बारे में बताता है.

उदाहरण के लिए, इस यूज़र इंटरफ़ेस (यूआई) ट्री को 300dp के कंटेनर में 200dp के हिसाब से रेंडर किया जाना चाहिए. ये सीमाएं तय की गई हैं. इसलिए, चौड़ाई 100dp और 300dp के बीच और ऊंचाई 100dp और 200dp के बीच होनी चाहिए:

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

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

यह इमेज, इमेज 7 जैसी ही है. हालांकि, इसमें साइज़ मॉडिफ़ायर, आने वाली सीमाओं को अडैप्ट करता है, ताकि वह पास की गई वैल्यू से मैच कर सके.
आठवीं इमेज. size मॉडिफ़ायर, शर्तों को 150dp पर अडजस्ट कर रहा है.

अगर चौड़ाई और ऊंचाई, सबसे छोटी सीमा से कम या सबसे बड़ी सीमा से ज़्यादा है, तो मॉडिफ़ायर, पास की गई सीमाओं से ज़्यादा से ज़्यादा मेल खाता है. हालांकि, ऐसा करते समय वह इन सीमाओं का पालन करता है:

दो यूज़र इंटरफ़ेस (यूआई) ट्री और कंटेनर में उनके मिलते-जुलते प्रज़ेंटेशन. पहले उदाहरण में, साइज़ मॉडिफ़ायर, आने वाली सीमाओं को स्वीकार करता है. दूसरे उदाहरण में, साइज़ मॉडिफ़ायर, बहुत बड़ी सीमाओं के हिसाब से खुद को जितना हो सके उतना अडजस्ट करता है. इससे ऐसी सीमाएं मिलती हैं जो कंटेनर को भर देती हैं.
नौवीं इमेज. size मॉडिफ़ायर, पास की गई शर्त का पालन करता है.

ध्यान दें कि एक से ज़्यादा size मॉडिफ़ायर को एक साथ इस्तेमाल नहीं किया जा सकता. पहले size मॉडिफ़ायर से, कम से कम और ज़्यादा से ज़्यादा वैल्यू की सीमाएं एक तय वैल्यू पर सेट हो जाती हैं. अगर साइज़ में बदलाव करने वाला दूसरा पैरामीटर, छोटे या बड़े साइज़ का अनुरोध करता है, तो भी उसे पास की गई सटीक सीमाओं का पालन करना होगा. इसलिए, यह उन वैल्यू को नहीं बदलेगा:

यूज़र इंटरफ़ेस (यूआई) ट्री में साइज़ मॉडिफ़ायर की दो चेन और कंटेनर में उसका प्रज़ेंटेशन. यह पहली वैल्यू का नतीजा है, दूसरी वैल्यू का नहीं.
दसवीं इमेज. दो size मॉडिफ़ायर की चेन, जिसमें (50dp) में पास की गई दूसरी वैल्यू, पहली वैल्यू (100dp) को ओवरराइड नहीं करती है.

requiredSize मॉडिफ़ायर

अगर आपको अपने नोड को आने वाली पाबंदियों को बदलने की अनुमति देनी है, तो size के बजाय requiredSize मॉडिफ़ायर का इस्तेमाल करें. requiredSize मॉडिफ़ायर, आने वाली सीमाओं को बदल देता है. साथ ही, आपके तय किए गए साइज़ को सटीक सीमा के तौर पर पास करता है.

जब साइज़ को ट्री में वापस ऊपर की ओर पास किया जाता है, तो चाइल्ड नोड को उपलब्ध जगह के बीच में रखा जाएगा:

यूज़र इंटरफ़ेस (यूआई) ट्री में साइज़ और requiredSize मॉडिफ़ायर को चेन किया गया है. साथ ही, कंटेनर में इसका कॉरस्पॉन्डिंग प्रज़ेंटेशन दिखाया गया है. requiredSize मॉडिफ़ायर की सीमाएं, size मॉडिफ़ायर की सीमाओं को बदल देती हैं.
इमेज 11. requiredSize मॉडिफ़ायर, size मॉडिफ़ायर से मिली शर्तों को बदल रहा है.

width और height मॉडिफ़ायर

size मॉडिफ़ायर, चौड़ाई और ऊंचाई, दोनों को अडजस्ट करता है. width मॉडिफ़ायर की मदद से, चौड़ाई को तय किया जा सकता है. हालांकि, ऊंचाई को तय नहीं किया जा सकता. इसी तरह, height मॉडिफ़ायर की मदद से, इमेज की ऊंचाई सेट की जा सकती है. हालांकि, चौड़ाई को तय नहीं किया जा सकता:

दो यूज़र इंटरफ़ेस (यूआई) ट्री. एक में चौड़ाई मॉडिफ़ायर और उसके कंटेनर का प्रज़ेंटेशन है. दूसरे में ऊंचाई मॉडिफ़ायर और उसका प्रज़ेंटेशन है.
इमेज 12. width मॉडिफ़ायर और height मॉडिफ़ायर, चौड़ाई और ऊंचाई को तय करते हैं.

sizeIn मॉडिफ़ायर

sizeIn मॉडिफ़ायर की मदद से, चौड़ाई और ऊंचाई के लिए कम से कम और ज़्यादा से ज़्यादा सीमाएं सेट की जा सकती हैं. अगर आपको शर्तों पर ज़्यादा कंट्रोल चाहिए, तो sizeIn मॉडिफ़ायर का इस्तेमाल करें.

कम से कम और ज़्यादा से ज़्यादा चौड़ाई और ऊंचाई सेट करने वाले sizeIn मॉडिफ़ायर के साथ यूज़र इंटरफ़ेस (यूआई) ट्री,
  और कंटेनर में उसका प्रज़ेंटेशन.
13वीं इमेज. minWidth, maxWidth, minHeight, और maxHeight सेट के साथ sizeIn मॉडिफ़ायर.

उदाहरण

इस सेक्शन में, चेन किए गए मॉडिफ़ायर के साथ कई कोड स्निपेट से मिले आउटपुट को दिखाया गया है और उनके बारे में बताया गया है.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .size(50.dp)
)

इस स्निपेट से यह आउटपुट मिलता है:

नीले रंग का एक स्क्वेयर, जो अपने पैरंट कंटेनर को भरता है.
चौदहवीं इमेज. मॉडिफ़ायर चेन की वजह से, Image ज़्यादा से ज़्यादा साइज़ में दिखता है.
  • fillMaxSize मॉडिफ़ायर, कम से कम चौड़ाई और ऊंचाई, दोनों को ज़्यादा से ज़्यादा वैल्यू पर सेट करने के लिए, कंस्ट्रेंट में बदलाव करता है. चौड़ाई में 300dp और ऊंचाई में 200dp.
  • भले ही, size मॉडिफ़ायर को 50dp के साइज़ का इस्तेमाल करना हो, लेकिन उसे अब भी कम से कम इनपुट की शर्तों का पालन करना होगा. इसलिए, size मॉडिफ़ायर, 200 के हिसाब से 300 के सटीक कंस्ट्रेंट बाउंड भी आउटपुट करेगा. इससे size मॉडिफ़ायर में दी गई वैल्यू को अनदेखा किया जा सकेगा.
  • Image इन सीमाओं का पालन करता है और 300 को 200 के साइज़ के तौर पर रिपोर्ट करता है. यह जानकारी पूरे ट्री में पास की जाती है.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .fillMaxSize()
        .wrapContentSize()
        .size(50.dp)
)

इस स्निपेट से यह आउटपुट मिलता है:

नीले रंग का छोटा स्क्वेयर, जो अपने पैरंट कंटेनर के बीच में है.
इमेज 15. Image को बीच में रखा गया है और इसका साइज़ 50dp है.
  • fillMaxSize मॉडिफ़ायर, चौड़ाई और ऊंचाई की कम से कम वैल्यू को ज़्यादा से ज़्यादा वैल्यू पर सेट करने के लिए, कंस्ट्रेंट को अडैप्ट करता है. चौड़ाई के लिए 300dp और ऊंचाई के लिए 200dp.
  • wrapContentSize मॉडिफ़ायर, कम से कम पाबंदियों को रीसेट करता है. इसलिए, fillMaxSize से कंस्ट्रेंट तय हो जाते हैं, जबकि wrapContentSize से कंस्ट्रेंट को वापस बाउंडेड कंस्ट्रेंट पर रीसेट कर दिया जाता है. अब यह नोड, पूरी जगह फिर से ले सकता है या पूरी जगह से छोटा हो सकता है.
  • size मॉडिफ़ायर, 50 की कम से कम और ज़्यादा से ज़्यादा सीमाएं सेट करता है.
  • Image, 50 x 50 के साइज़ में बदल जाता है. साथ ही, size मॉडिफ़ायर उसे आगे बढ़ाता है.
  • wrapContentSize मॉडिफ़ायर की एक खास प्रॉपर्टी होती है. यह अपने चाइल्ड को लेता है और उसे उपलब्ध कम से कम बाउंड्री के बीच में रखता है, जो इसे पास की गई थीं. इसलिए, यह अपने पैरंट को जो साइज़ बताता है वह इसमें पास किए गए कम से कम बाउंड के बराबर होता है.

सिर्फ़ तीन मॉडिफ़ायर को मिलाकर, कंपोज़ेबल के लिए साइज़ तय किया जा सकता है. साथ ही, इसे इसके पैरंट में बीच में रखा जा सकता है.

Image(
    painterResource(R.drawable.hero),
    contentDescription = null,
    Modifier
        .clip(CircleShape)
        .padding(10.dp)
        .size(100.dp)
)

इस स्निपेट से यह आउटपुट मिलता है:

मॉडिफ़ायर के क्रम की वजह से, गलत तरीके से काटा गया गोलाकार.
16वीं इमेज. मॉडिफ़ायर के क्रम की वजह से, गलत तरीके से काटा गया आकार.
  • clip मॉडिफ़ायर से, शर्तों में कोई बदलाव नहीं होता.
  • padding मॉडिफ़ायर, ज़्यादा से ज़्यादा पाबंदियों को कम करता है.
  • size मॉडिफ़ायर, सभी शर्तों को 100dp पर सेट करता है.
  • Image उन शर्तों का पालन करता है और 100dp के हिसाब से 100dp का साइज़ दिखाता है.
  • padding मॉडिफ़ायर, Image से रिपोर्ट किए गए साइज़ में चारों ओर 10dp जोड़ता है. इसलिए, पैडिंग वाले लेआउट की चौड़ाई और ऊंचाई 120dp होती है.
  • अब ड्राइंग फ़ेज़ में, clip मॉडिफ़ायर, 120dp के कैनवस पर 120dp के हिसाब से काम करता है. इससे उस साइज़ का एक सर्कल मास्क बनता है.
  • इसके बाद, padding मॉडिफ़ायर अपने कॉन्टेंट को चारों ओर से 10dp पर सेट करता है. इससे Image का कैनवस साइज़ 100dp से 100dp तक कम हो जाता है.
  • Image को उस छोटे कैनवस में बनाया जाता है. इमेज को 120dp के ओरिजनल सर्कल के आधार पर काटा जाता है. इसलिए, आउटपुट गोल नहीं होता.