जब आपकी गतिविधि सभी इनसेट को मैनेज करने का कंट्रोल ले लेती है, तब Compose API का इस्तेमाल करके यह पक्का किया जा सकता है कि कॉन्टेंट छिपा न हो और इंटरैक्ट किए जा सकने वाले एलिमेंट, सिस्टम यूज़र इंटरफ़ेस के साथ ओवरलैप न हों. ये एपीआई, आपके ऐप्लिकेशन के लेआउट को इनसेट में किए गए बदलावों के साथ सिंक भी करते हैं.
उदाहरण के लिए, अपने पूरे ऐप्लिकेशन के कॉन्टेंट में इनसेट लागू करने का यह सबसे बुनियादी तरीका है:
override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { Box(Modifier.safeDrawingPadding()) { // the rest of the app } } }
यह स्निपेट, ऐप्लिकेशन के पूरे कॉन्टेंट के चारों ओर पैडिंग के तौर पर safeDrawing
विंडो इनसेट लागू करता है. इससे यह पक्का होता है कि इंटरैक्ट किए जा सकने वाले एलिमेंट, सिस्टम यूज़र इंटरफ़ेस (यूआई) के साथ ओवरलैप न हों. इसका यह भी मतलब है कि ऐप्लिकेशन का कोई भी हिस्सा, किनारों से किनारों तक का असर पाने के लिए, सिस्टम यूज़र इंटरफ़ेस (यूआई) के पीछे नहीं दिखेगा. पूरी विंडो का पूरा फ़ायदा पाने के लिए, आपको यह तय करना होगा कि इनसेट को स्क्रीन के हिसाब से या कॉम्पोनेंट के हिसाब से कहां लागू करना है.
इनसेट के सभी टाइप, एपीआई 21 में वापस पोर्ट किए गए IME ऐनिमेशन के साथ अपने-आप ऐनिमेट होते हैं. इनसेट की वैल्यू बदलने पर, इनसेट का इस्तेमाल करने वाले सभी लेआउट भी अपने-आप ऐनिमेट हो जाते हैं.
अपने Composable लेआउट में बदलाव करने के लिए, इनसेट टाइप का इस्तेमाल करने के दो मुख्य तरीके हैं: पैडिंग मॉडिफ़ायर और इनसेट साइज़ मॉडिफ़ायर.
पैडिंग मॉडिफ़ायर
Modifier.windowInsetsPadding(windowInsets: WindowInsets)
, दी गई विंडो इनसेट को पैडिंग के तौर पर लागू करता है. यह ठीक वैसे ही काम करता है जैसे Modifier.padding
करता है.
उदाहरण के लिए, Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
, सेफ़ ड्रॉइंग इनसेट को चारों तरफ़ पैडिंग के तौर पर लागू करता है.
आम तौर पर इस्तेमाल होने वाले इनसेट टाइप के लिए, कई उपयोगी तरीके पहले से मौजूद हैं.
Modifier.safeDrawingPadding()
एक ऐसा तरीका है जो Modifier.windowInsetsPadding(WindowInsets.safeDrawing)
के बराबर है. इनसे मिलते-जुलते, अन्य इनसेट टाइप के लिए भी मॉडिफ़ायर उपलब्ध हैं.
इनसेट साइज़ मॉडिफ़ायर
नीचे दिए गए मॉडिफ़ायर, कॉम्पोनेंट के साइज़ को इनसेट के साइज़ के तौर पर सेट करके, विंडो इनसेट की संख्या लागू करते हैं:
windowInsets के स्टार्ट साइड को चौड़ाई के तौर पर लागू करता है (जैसे कि |
|
windowInsets के आखिरी हिस्से को चौड़ाई के तौर पर लागू करता है, जैसे कि |
|
windowInsets के ऊपरी हिस्से को ऊंचाई के तौर पर लागू करता है (जैसे कि |
|
|
windowInsets के नीचे की ओर की वैल्यू को ऊंचाई के तौर पर लागू करता है, जैसे कि |
ये मॉडिफ़ायर, खास तौर पर ऐसे Spacer
का साइज़ तय करने के लिए मददगार होते हैं जो इनसेट का स्पेस लेता है:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
इनसेट की खपत
इनसेट पैडिंग मॉडिफ़ायर (windowInsetsPadding
और safeDrawingPadding
जैसे सहायक), इनसेट के उस हिस्से का इस्तेमाल अपने-आप करते हैं जिसे पैडिंग के तौर पर लागू किया जाता है. कॉम्पोज़िशन ट्री में ज़्यादा अंदर जाने पर, नेस्ट किए गए इनसेट पैडिंग मॉडिफ़ायर और इनसेट साइज़ मॉडिफ़ायर को पता चलता है कि इनसेट के कुछ हिस्से का इस्तेमाल, आउटर इनसेट पैडिंग मॉडिफ़ायर ने पहले ही कर लिया है. साथ ही, इनसेट के एक ही हिस्से का एक से ज़्यादा बार इस्तेमाल करने से बचते हैं, क्योंकि इससे बहुत ज़्यादा अतिरिक्त स्पेस बन जाता है.
अगर इनसेट का इस्तेमाल पहले ही किया जा चुका है, तो इनसेट साइज़ में बदलाव करने वाले टूल, इनसेट के एक ही हिस्से का एक से ज़्यादा बार इस्तेमाल करने से भी बचते हैं. हालांकि, इनसे अपने साइज़ में सीधे तौर पर बदलाव किया जाता है. इसलिए, ये इनसेट का इस्तेमाल नहीं करते.
इस वजह से, नेस्ट किए गए पैडिंग मॉडिफ़ायर, हर कॉम्पोज़ेबल पर लागू किए गए पैडिंग की मात्रा को अपने-आप बदल देते हैं.
पहले की तरह ही LazyColumn
के उदाहरण को देखें. इसमें LazyColumn
का साइज़, imePadding
मॉडिफ़ायर की मदद से बदला जा रहा है. LazyColumn
में, आखिरी आइटम का साइज़, सिस्टम बार के सबसे नीचे की ऊंचाई के बराबर होता है:
LazyColumn( Modifier.imePadding() ) { // Other content item { Spacer( Modifier.windowInsetsBottomHeight( WindowInsets.systemBars ) ) } }
जब IME बंद होता है, तो imePadding()
मॉडिफ़ायर कोई पैडिंग लागू नहीं करता, क्योंकि IME की कोई ऊंचाई नहीं होती. imePadding()
मॉडिफ़ायर कोई पैडिंग लागू नहीं कर रहा है, इसलिए कोई इनसेट इस्तेमाल नहीं किया जा रहा है. साथ ही, Spacer
की ऊंचाई, सिस्टम बार के सबसे नीचे वाले हिस्से के साइज़ के बराबर होगी.
IME खुलने पर, IME इनसेट ऐनिमेशन के साथ IME के साइज़ से मैच हो जाते हैं. साथ ही, IME खुलने पर imePadding()
मॉडिफ़ायर, LazyColumn
का साइज़ बदलने के लिए बॉटम पैडिंग लागू करना शुरू कर देता है. जब imePadding()
मॉडिफ़ायर, सबसे नीचे पैडिंग लागू करना शुरू करता है, तो वह उतने ही इनसेट का इस्तेमाल करना शुरू कर देता है. इसलिए, Spacer
की ऊंचाई कम होने लगती है, क्योंकि imePadding()
मॉडिफ़ायर ने सिस्टम बार के लिए स्पेसिंग का कुछ हिस्सा पहले ही लागू कर दिया है. जब imePadding()
मॉडिफ़ायर, सबसे नीचे इतना पैडिंग लागू करता है कि वह सिस्टम बार से ज़्यादा हो जाता है, तो Spacer
की ऊंचाई शून्य हो जाती है.
IME बंद होने पर, ये बदलाव उलटे क्रम में होते हैं: imePadding()
के सिस्टम बार के सबसे नीचे वाले हिस्से से कम लागू होने पर, Spacer
शून्य की ऊंचाई से बड़ा होना शुरू हो जाता है. आखिर में, IME पूरी तरह से ऐनिमेशन के साथ बंद होने पर, Spacer
की ऊंचाई, सिस्टम बार के सबसे नीचे वाले हिस्से की ऊंचाई से मेल खाती है.
TextField
के साथ, किनारे से किनारे तक लेज़ी कॉलम.यह व्यवहार, सभी windowInsetsPadding
मॉडिफ़ायर के बीच बातचीत के ज़रिए पूरा किया जाता है. साथ ही, इस पर कुछ और तरीकों से असर पड़ सकता है.
Modifier.consumeWindowInsets(insets: WindowInsets)
भी Modifier.windowInsetsPadding
की तरह ही इनसेट का इस्तेमाल करता है. हालांकि, यह इस्तेमाल किए गए इनसेट को पैडिंग के तौर पर लागू नहीं करता. यह इनसेट साइज़ में बदलाव करने वाले टूल के साथ इस्तेमाल करने के लिए मददगार है. इससे, सिबलिंग को यह पता चलता है कि कुछ इनसेट पहले ही इस्तेमाल हो चुके हैं:
Column(Modifier.verticalScroll(rememberScrollState())) { Spacer(Modifier.windowInsetsTopHeight(WindowInsets.systemBars)) Column( Modifier.consumeWindowInsets( WindowInsets.systemBars.only(WindowInsetsSides.Vertical) ) ) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) } Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.systemBars)) }
Modifier.consumeWindowInsets(paddingValues: PaddingValues)
, WindowInsets
आर्ग्युमेंट वाले वर्शन की तरह ही काम करता है. हालांकि, इसे इस्तेमाल करने के लिए, मनमुताबिक PaddingValues
लेना होता है. यह बच्चों को बताने के लिए काम का है कि जब पैडिंग या स्पेसिंग, इनसेट पैडिंग मॉडिफ़ायर के बजाय किसी दूसरे तरीके से दी जाती है, तो क्या होता है. जैसे, सामान्य Modifier.padding
या तय की गई ऊंचाई वाले स्पेसर्स:
Column(Modifier.padding(16.dp).consumeWindowInsets(PaddingValues(16.dp))) { // content Spacer(Modifier.windowInsetsBottomHeight(WindowInsets.ime)) }
जिन मामलों में बिना खर्च किए रॉ विंडो इनसेट की ज़रूरत होती है उनमें सीधे WindowInsets
वैल्यू का इस्तेमाल करें. इसके अलावा, WindowInsets.asPaddingValues()
का इस्तेमाल करके, उन इनसेट का PaddingValues
दिखाएं जिन पर खर्च का असर नहीं पड़ता.
हालांकि, यहां दी गई सावधानियों की वजह से, जहां भी हो सके वहां विंडो इनसेट पैडिंग में बदलाव करने वाले और विंडो इनसेट के साइज़ में बदलाव करने वाले टूल का इस्तेमाल करें.
इनसेट और Jetpack Compose के फ़ेज़
Compose, इनसेट को अपडेट करने और ऐनिमेट करने के लिए, AndroidX के मुख्य एपीआई का इस्तेमाल करता है. ये एपीआई, इनसेट को मैनेज करने वाले प्लैटफ़ॉर्म एपीआई का इस्तेमाल करते हैं. प्लैटफ़ॉर्म के इस व्यवहार की वजह से, इनसेट का Jetpack Compose के चरणों से खास संबंध है.
इनसेट की वैल्यू, कंपोज़िशन फ़ेज़ के बाद, लेकिन लेआउट फ़ेज़ के पहले अपडेट की जाती है. इसका मतलब है कि कॉम्पोज़िशन में इनसेट की वैल्यू पढ़ने के लिए, आम तौर पर इनसेट की उस वैल्यू का इस्तेमाल किया जाता है जो एक फ़्रेम पहले की होती है. इस पेज पर बताए गए, पहले से मौजूद मॉडिफ़ायर, इनसेट की वैल्यू का इस्तेमाल, लेआउट फ़ेज़ तक करने में देरी करने के लिए बनाए गए हैं. इससे यह पक्का होता है कि इनसेट की वैल्यू, अपडेट होने के बाद उसी फ़्रेम पर इस्तेमाल की जाती हैं.