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

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

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

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

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

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

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

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

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

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

Row और Column के लागू होने का तरीका, लेआउट नोड होता है. इससे पता चलता है कि उनके चाइल्ड नोड को कैसे लेआउट करना है.

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

खास जानकारी:

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

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

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

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

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

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

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

शर्त इनमें से कोई एक हो सकती है:

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

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

कंस्ट्रेंट, पैरंट से चाइल्ड तक कैसे पास होते हैं

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

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

एल्गोरिदम इस तरह से काम करता है:

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

ज़्यादा जानकारी के लिए, कंस्ट्रेंट और मॉडिफ़ायर का क्रम वीडियो देखें.

पाबंदियों पर असर डालने वाले मॉडिफ़ायर

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

size मॉडिफ़ायर

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

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

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

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

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

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

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

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

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

requiredSize मॉडिफ़ायर

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

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

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

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

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

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

sizeIn मॉडिफ़ायर

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

एक यूज़र इंटरफ़ेस (यूआई) ट्री, जिसमें sizeIn मॉडिफ़ायर का इस्तेमाल करके, कम से कम और ज़्यादा से ज़्यादा चौड़ाई और लंबाई सेट की गई है. साथ ही, इसे एक कंटेनर में दिखाया गया है.
इमेज 13. sizeIn मॉडिफ़ायर, जिसमें minWidth, maxWidth, minHeight, और maxHeight सेट है.

उदाहरण

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

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

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

एक नीला स्क्वेयर, जो अपने पैरंट कंटेनर को भरता है.
इमेज 14. Image, मॉडिफ़ायर चेन की वजह से ज़्यादा से ज़्यादा साइज़ भरता है.
  • fillMaxSize मॉडिफ़ायर, कंस्ट्रेंट में बदलाव करता है, ताकि कम से कम चौड़ाई और ऊंचाई को ज़्यादा से ज़्यादा वैल्यू पर सेट किया जा सके. जैसे, चौड़ाई को 300dp और ऊंचाई को 200dp पर सेट किया जा सकता है.
  • भले ही, size मॉडिफ़ायर 50dp साइज़ का इस्तेमाल करना चाहता हो, लेकिन उसे अब भी कम से कम साइज़ की पाबंदियों का पालन करना होगा. इसलिए, size मॉडिफ़ायर, 300 और 200 के सटीक कंस्ट्रेंट बाउंड भी आउटपुट करेगा. साथ ही, size मॉडिफ़ायर में दी गई वैल्यू को अनदेखा कर देगा.
  • Image इन सीमाओं का पालन करता है और 300 x 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 x 100dp साइज़ की रिपोर्ट करता है.
  • padding मॉडिफ़ायर, Image से रिपोर्ट किए गए साइज़ में सभी तरफ़ 10dp जोड़ता है. इसलिए, पैडिंग वाले लेआउट की चौड़ाई और ऊंचाई 120dp होती है.
  • अब ड्रॉइंग फ़ेज़ में, clip मॉडिफ़ायर 120dp x 120dp के कैनवस पर काम करता है. यह उस साइज़ का सर्कल मास्क बनाता है.
  • इसके बाद, padding मॉडिफ़ायर अपने कॉन्टेंट को सभी तरफ़ से 10dp इनसेट करता है. इससे Image के लिए कैनवस का साइज़ 100dp से 100dp कम हो जाता है.
  • Image को उस छोटे कैनवस में ड्रॉ किया जाता है. इमेज को 120dp के ओरिजनल सर्कल के आधार पर क्लिप किया जाता है. इसलिए, आउटपुट गोल नहीं होता.