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

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

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

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

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

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

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

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

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

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

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

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

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

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

लेआउट फ़ेज़ में आने वाली समस्याएं

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

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

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

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

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

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

अगले सेक्शन में बताया गया है कि ये पाबंदियां, माता-पिता से बच्चे पर कैसे लागू होती हैं.

पैरंट से चाइल्ड में पाबंदियां कैसे भेजी जाती हैं

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

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

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

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

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

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

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

size मॉडिफ़ायर

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

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

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

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

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

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

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

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

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

requiredSize मॉडिफ़ायर

अगर आपको अपने नोड को आने वाली पाबंदियों को बदलना है, तो size के बजाय 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)
)

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

  • 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)
)

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

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

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

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

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

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