Compose में, एक से ज़्यादा मॉडिफ़ायर को एक साथ जोड़कर, किसी कंपोज़ेबल के लुक और स्टाइल को बदला जा सकता है. इन मॉडिफ़ायर चेन से, कंपोज़ेबल को पास की गई सीमाओं पर असर पड़ सकता है. ये सीमाएं, चौड़ाई और ऊंचाई की सीमाओं को तय करती हैं.
इस पेज पर बताया गया है कि चेन किए गए मॉडिफ़ायर, कंस्ट्रेंट पर कैसे असर डालते हैं. साथ ही, कंपोज़ेबल के मेज़रमेंट और प्लेसमेंट पर इनका क्या असर पड़ता है.
यूज़र इंटरफ़ेस (यूआई) ट्री में मॉडिफ़ायर
मॉडिफ़ायर एक-दूसरे पर कैसे असर डालते हैं, यह समझने के लिए यह देखना मददगार होता है कि वे यूज़र इंटरफ़ेस (यूआई) ट्री में कैसे दिखते हैं. यह ट्री, कंपोज़िशन फ़ेज़ के दौरान जनरेट होता है. ज़्यादा जानकारी के लिए, कंपोज़िशन सेक्शन देखें.
यूज़र इंटरफ़ेस (यूआई) ट्री में, मॉडिफ़ायर को लेआउट नोड के लिए रैपर नोड के तौर पर विज़ुअलाइज़ किया जा सकता है:
किसी कंपोज़ेबल में एक से ज़्यादा मॉडिफ़ायर जोड़ने पर, मॉडिफ़ायर की एक चेन बन जाती है. एक से ज़्यादा मॉडिफ़ायर को चेन करने पर, हर मॉडिफ़ायर नोड, चेन के बाकी हिस्से और लेआउट नोड को रैप करता है. उदाहरण के लिए, जब clip और size मॉडिफ़ायर को चेन किया जाता है, तो clip मॉडिफ़ायर नोड, size मॉडिफ़ायर नोड को रैप करता है. इसके बाद, यह Image लेआउट नोड को रैप करता है.
लेआउट फ़ेज़ में, ट्री को वॉक करने वाला एल्गोरिदम पहले जैसा ही रहता है. हालांकि, हर मॉडिफ़ायर नोड पर भी विज़िट किया जाता है. इस तरह, मॉडिफ़ायर अपने रैप किए गए मॉडिफ़ायर या लेआउट नोड के साइज़ की ज़रूरी शर्तों और प्लेसमेंट में बदलाव कर सकता है.
जैसा कि इमेज 2 में दिखाया गया है, Image और Text कंपोज़ेबल को लागू करने के लिए, एक लेआउट नोड को रैप करने वाले मॉडिफ़ायर की चेन होती है.
Row और Column के लागू होने का तरीका, लेआउट नोड होता है. इससे पता चलता है कि उनके चाइल्ड नोड को कैसे लेआउट करना है.
खास जानकारी:
- मॉडिफ़ायर, किसी एक मॉडिफ़ायर या लेआउट नोड को रैप करते हैं.
- लेआउट नोड, कई चाइल्ड नोड को लेआउट कर सकते हैं.
यहां दिए गए सेक्शन में, इस मेंटल मॉडल का इस्तेमाल करने का तरीका बताया गया है. इससे, मॉडिफ़ायर चेनिंग के बारे में जानकारी मिलती है. साथ ही, यह भी पता चलता है कि यह कंपोज़ेबल के साइज़ पर कैसे असर डालता है.
लेआउट फ़ेज़ में कंस्ट्रेंट
लेआउट फ़ेज़ में, हर लेआउट नोड की चौड़ाई, ऊंचाई, और x, y निर्देशांक का पता लगाने के लिए, तीन चरणों वाला एल्गोरिदम इस्तेमाल किया जाता है:
- चाइल्ड एलिमेंट को मेज़र करना: कोई नोड अपने चाइल्ड एलिमेंट को मेज़र करता है, अगर कोई चाइल्ड एलिमेंट मौजूद हो.
- साइज़ तय करना: इन मेज़रमेंट के आधार पर, नोड खुद ही अपना साइज़ तय करता है.
- चाइल्ड नोड को प्लेस करना: हर चाइल्ड नोड को नोड की अपनी पोज़िशन के हिसाब से प्लेस किया जाता है.
Constraints, एल्गोरिदम के पहले दो चरणों के दौरान, नोड के लिए सही साइज़ ढूंढने में मदद करते हैं. कंस्ट्रेंट, किसी नोड की चौड़ाई और ऊंचाई की कम से कम और ज़्यादा से ज़्यादा सीमा तय करते हैं. जब नोड अपने साइज़ का फ़ैसला करता है, तो उसका मेज़र किया गया साइज़, इस साइज़ रेंज के अंदर होना चाहिए.
अलग-अलग तरह की पाबंदियां
शर्त इनमें से कोई एक हो सकती है:
- बाउंडेड: नोड की ज़्यादा से ज़्यादा और कम से कम चौड़ाई और ऊंचाई होती है.
- अनबाउंडेड: नोड किसी भी साइज़ तक सीमित नहीं है. चौड़ाई और ऊंचाई की ज़्यादा से ज़्यादा सीमाएं, इनफ़िनिटी पर सेट हैं.
- Exact: नोड को साइज़ की सटीक शर्त का पालन करने के लिए कहा जाता है. कम से कम और ज़्यादा से ज़्यादा सीमाएं, एक ही वैल्यू पर सेट की गई हैं.
- कॉम्बिनेशन: नोड, ऊपर बताई गई पाबंदियों के कॉम्बिनेशन का पालन करता है. उदाहरण के लिए, कोई कंस्ट्रेंट चौड़ाई को सीमित कर सकता है, लेकिन ज़्यादा से ज़्यादा ऊंचाई को सीमित नहीं कर सकता. इसके अलावा, वह सटीक चौड़ाई सेट कर सकता है, लेकिन ऊंचाई को सीमित कर सकता है.
अगले सेक्शन में बताया गया है कि ये पाबंदियां, पैरंट से चाइल्ड तक कैसे पहुंचती हैं.
कंस्ट्रेंट, पैरंट से चाइल्ड तक कैसे पास होते हैं
लेआउट फ़ेज़ में पाबंदियां सेक्शन में बताए गए एल्गोरिदम के पहले चरण के दौरान, यूज़र इंटरफ़ेस (यूआई) ट्री में पाबंदियां पैरंट से चाइल्ड को पास की जाती हैं.
जब कोई पैरंट नोड अपने चाइल्ड नोड को मेज़र करता है, तो वह हर चाइल्ड नोड को ये कंस्ट्रेंट देता है, ताकि उन्हें पता चल सके कि वे कितने बड़े या छोटे हो सकते हैं. इसके बाद, जब यह अपना साइज़ तय करता है, तो यह उन पाबंदियों का भी पालन करता है जो इसके पैरंट ने पास की थीं.
एल्गोरिदम इस तरह से काम करता है:
- यूज़र इंटरफ़ेस (यूआई) ट्री में रूट नोड, अपने चाइल्ड नोड को मेज़र करता है और पहले चाइल्ड नोड को वही कंस्ट्रेंट फ़ॉरवर्ड करता है. इससे यह तय होता है कि उसे असल में कितना साइज़ चाहिए.
- अगर चाइल्ड नोड एक ऐसा मॉडिफ़ायर है जो मेज़रमेंट पर असर नहीं डालता, तो यह पाबंदियों को अगले मॉडिफ़ायर पर फ़ॉरवर्ड कर देता है. कंस्ट्रेंट को मॉडिफ़ायर चेन में तब तक पास किया जाता है, जब तक कि मेज़रमेंट पर असर डालने वाला कोई मॉडिफ़ायर न मिल जाए. इसके बाद, पाबंदियों का साइज़ उसी हिसाब से बदल जाता है.
- जब कोई नोड ऐसे नोड पर पहुंचता है जिसमें कोई चाइल्ड नोड नहीं होता (इसे "लीफ नोड" कहा जाता है), तो वह पास की गई पाबंदियों के आधार पर अपना साइज़ तय करता है. साथ ही, इस साइज़ को अपने पैरंट नोड को वापस भेजता है.
- पैरंट विजेट, चाइल्ड विजेट के साइज़ के हिसाब से अपनी सीमाओं में बदलाव करता है. इसके बाद, वह इन बदली हुई सीमाओं के साथ अपने अगले चाइल्ड विजेट को कॉल करता है.
- जब किसी पैरंट नोड के सभी चाइल्ड नोड का साइज़ तय हो जाता है, तब पैरंट नोड अपना साइज़ तय करता है और इसकी जानकारी अपने पैरंट नोड को देता है.
- इस तरह, पूरे ट्री को डेप्थ-फ़र्स्ट तरीके से ट्रैवर्स किया जाता है. आखिर में, सभी नोड अपने साइज़ तय कर लेते हैं और मेज़रमेंट का चरण पूरा हो जाता है.
ज़्यादा जानकारी के लिए, कंस्ट्रेंट और मॉडिफ़ायर का क्रम वीडियो देखें.
पाबंदियों पर असर डालने वाले मॉडिफ़ायर
आपने पिछले सेक्शन में जाना कि कुछ मॉडिफ़ायर, कंस्ट्रेंट के साइज़ पर असर डाल सकते हैं. यहां दिए गए सेक्शन में, उन खास मॉडिफ़ायर के बारे में बताया गया है जो कंस्ट्रेंट पर असर डालते हैं.
size मॉडिफ़ायर
size मॉडिफ़ायर, कॉन्टेंट के पसंदीदा साइज़ के बारे में बताता है.
उदाहरण के लिए, यहां दिए गए यूज़र इंटरफ़ेस (यूआई) ट्री को 300dp x 200dp के कंटेनर में रेंडर किया जाना चाहिए. कंस्ट्रेंट की सीमाएं तय हैं. इनमें चौड़ाई 100dp से 300dp के बीच और ऊंचाई 100dp से 200dp के बीच होनी चाहिए:
size मॉडिफ़ायर, इनकमिंग कंस्ट्रेंट को अडजस्ट करता है, ताकि वे पास की गई वैल्यू से मैच कर सकें.
इस उदाहरण में, वैल्यू 150dp है:
size मॉडिफ़ायर, पाबंदियों को 150dp पर अडजस्ट करता है.अगर चौड़ाई और ऊंचाई, सबसे छोटी सीमा से छोटी है या सबसे बड़ी सीमा से बड़ी है, तो मॉडिफ़ायर, पास की गई सीमाओं से ज़्यादा से ज़्यादा मैच करता है. हालांकि, यह पास की गई सीमाओं का पालन करता है:
size मॉडिफ़ायर, पास की गई पाबंदी का ज़्यादा से ज़्यादा पालन करता है.ध्यान दें कि एक से ज़्यादा size मॉडिफ़ायर को चेन करने से काम नहीं बनता. पहला size मॉडिफ़ायर, कम से कम और ज़्यादा से ज़्यादा, दोनों सीमाओं को एक तय वैल्यू पर सेट करता है. अगर दूसरा साइज़ मॉडिफ़ायर, छोटे या बड़े साइज़ का अनुरोध करता है, तो भी उसे पास की गई सटीक सीमाओं का पालन करना होगा. इसलिए, वह उन वैल्यू को ओवरराइड नहीं करेगा:
size मॉडिफ़ायर की चेन, जिसमें पास की गई दूसरी वैल्यू (50dp), पहली वैल्यू (100dp) को बदल नहीं सकती.requiredSize मॉडिफ़ायर
अगर आपको अपने नोड को इनकमिंग कंस्ट्रेंट को बदलने की ज़रूरत है, तो size के बजाय requiredSize मॉडिफ़ायर का इस्तेमाल करें. requiredSize मॉडिफ़ायर, इनकमिंग कंस्ट्रेंट को बदल देता है. साथ ही, आपके तय किए गए साइज़ को सटीक बाउंड के तौर पर पास करता है.
जब साइज़ को ट्री में वापस पास किया जाता है, तो चाइल्ड नोड को उपलब्ध जगह के बीच में रखा जाएगा:
requiredSize मॉडिफ़ायर, size मॉडिफ़ायर से आने वाली पाबंदियों को बदल रहा है.width और height मॉडिफ़ायर
size मॉडिफ़ायर, कंस्ट्रेंट की चौड़ाई और ऊंचाई, दोनों को अडजस्ट करता है. width मॉडिफ़ायर की मदद से, चौड़ाई को तय किया जा सकता है, लेकिन ऊंचाई को तय नहीं किया जा सकता.
इसी तरह, height मॉडिफ़ायर की मदद से, तय ऊंचाई सेट की जा सकती है. हालांकि, चौड़ाई को तय नहीं किया जा सकता:
width मॉडिफ़ायर और height मॉडिफ़ायर, तय चौड़ाई और ऊंचाई सेट करते हैं.sizeIn मॉडिफ़ायर
sizeIn मॉडिफ़ायर की मदद से, चौड़ाई और ऊंचाई के लिए कम से कम और ज़्यादा से ज़्यादा सटीक सीमाएं सेट की जा सकती हैं. अगर आपको पाबंदियों पर ज़्यादा कंट्रोल चाहिए, तो sizeIn मॉडिफ़ायर का इस्तेमाल करें.
sizeIn मॉडिफ़ायर, जिसमें minWidth, maxWidth, minHeight, और
maxHeight सेट है.उदाहरण
इस सेक्शन में, चेन किए गए मॉडिफ़ायर वाले कई कोड स्निपेट का आउटपुट दिखाया गया है और उसके बारे में बताया गया है.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
इस स्निपेट से यह आउटपुट मिलता है:
Image, मॉडिफ़ायर चेन की वजह से ज़्यादा से ज़्यादा साइज़ भरता है.fillMaxSizeमॉडिफ़ायर, कंस्ट्रेंट में बदलाव करता है, ताकि कम से कम चौड़ाई और ऊंचाई को ज़्यादा से ज़्यादा वैल्यू पर सेट किया जा सके. जैसे, चौड़ाई को300dpऔर ऊंचाई को200dpपर सेट किया जा सकता है.- भले ही,
sizeमॉडिफ़ायर50dpसाइज़ का इस्तेमाल करना चाहता हो, लेकिन उसे अब भी कम से कम साइज़ की पाबंदियों का पालन करना होगा. इसलिए,sizeमॉडिफ़ायर,300और200के सटीक कंस्ट्रेंट बाउंड भी आउटपुट करेगा. साथ ही,sizeमॉडिफ़ायर में दी गई वैल्यू को अनदेखा कर देगा. Imageइन सीमाओं का पालन करता है और300x200साइज़ की रिपोर्ट करता है. यह साइज़, ट्री में सबसे ऊपर तक पास किया जाता है.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
इस स्निपेट से यह आउटपुट मिलता है:
Image को बीच में रखा गया है और इसका साइज़ 50dp पर सेट किया गया है.fillMaxSizeमॉडिफ़ायर, कंस्ट्रेंट को अडैप्ट करता है, ताकि चौड़ाई और ऊंचाई, दोनों को ज़्यादा से ज़्यादा वैल्यू पर सेट किया जा सके. जैसे, चौड़ाई के लिए300dpऔर ऊंचाई के लिए200dp.wrapContentSizeमॉडिफ़ायर, कम से कम पाबंदियों को रीसेट करता है. इसलिए,fillMaxSizeसे तय की गई पाबंदियां लागू होती हैं, जबकिwrapContentSizeसे पाबंदियां फिर से सीमित हो जाती हैं. अब अगला नोड फिर से पूरी जगह ले सकता है या पूरी जगह से छोटा हो सकता है.sizeमॉडिफ़ायर,50की कम से कम और ज़्यादा से ज़्यादा सीमाओं को सेट करता है.Imageका साइज़50x50में बदल जाता है औरsizeमॉडिफ़ायर इसे आगे भेजता है.wrapContentSizeमॉडिफ़ायर में एक खास प्रॉपर्टी होती है. यह अपने चाइल्ड को लेता है और उसे उपलब्ध कम से कम बाउंड के बीच में रखता है, जो इसे पास किए गए थे. इसलिए, यह अपने पैरंट को जो साइज़ बताता है वह इसमें पास की गई कम से कम सीमाओं के बराबर होता है.
सिर्फ़ तीन मॉडिफ़ायर को जोड़कर, कंपोज़ेबल का साइज़ तय किया जा सकता है और उसे पैरंट के बीच में रखा जा सकता है.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
इस स्निपेट से यह आउटपुट मिलता है:
clipमॉडिफ़ायर, कंस्ट्रेंट में बदलाव नहीं करता.paddingमॉडिफ़ायर, ज़्यादा से ज़्यादा सीमाओं को कम करता है.sizeमॉडिफ़ायर, सभी कंस्ट्रेंट को100dpपर सेट करता है.Imageइन सीमाओं का पालन करता है और100dpx100dpसाइज़ की रिपोर्ट करता है.paddingमॉडिफ़ायर,Imageसे रिपोर्ट किए गए साइज़ में सभी तरफ़10dpजोड़ता है. इसलिए, पैडिंग वाले लेआउट की चौड़ाई और ऊंचाई120dpहोती है.- अब ड्रॉइंग फ़ेज़ में,
clipमॉडिफ़ायर120dpx120dpके कैनवस पर काम करता है. यह उस साइज़ का सर्कल मास्क बनाता है. - इसके बाद,
paddingमॉडिफ़ायर अपने कॉन्टेंट को सभी तरफ़ से10dpइनसेट करता है. इससेImageके लिए कैनवस का साइज़100dpसे100dpकम हो जाता है. Imageको उस छोटे कैनवस में ड्रॉ किया जाता है. इमेज को120dpके ओरिजनल सर्कल के आधार पर क्लिप किया जाता है. इसलिए, आउटपुट गोल नहीं होता.