विंडो इनसेट सेट अप करना

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

पैडिंग या साइज़ मॉडिफ़ायर का इस्तेमाल करके, इनसेट को मैनेज करना

उदाहरण के लिए, यहां आपके पूरे ऐप्लिकेशन के कॉन्टेंट में इंसर्ट लागू करने का सबसे बुनियादी तरीका बताया गया है:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    enableEdgeToEdge()

    setContent {
        Box(Modifier.safeDrawingPadding()) {
            // the rest of the app
        }
    }
}

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

ये सभी इंसर्ट टाइप, IME ऐनिमेशन के साथ अपने-आप ऐनिमेट हो जाते हैं. इन्हें एपीआई 21 पर वापस पोर्ट किया गया है. इसके अलावा, इन इनसेट का इस्तेमाल करने वाले आपके सभी लेआउट भी अपने-आप ऐनिमेट हो जाते हैं, क्योंकि इनसेट की वैल्यू बदल जाती हैं.

अपने कंपोज़ेबल लेआउट को अडजस्ट करने के लिए, इनसेट को मैनेज करने के तीन तरीके हैं:

पैडिंग मॉडिफ़ायर

Modifier.windowInsetsPadding(windowInsets: WindowInsets), दिए गए विंडो इंसर्ट को पैडिंग के तौर पर लागू करता है. यह ठीक वैसे ही काम करता है जैसे Modifier.padding करता है. उदाहरण के लिए, Modifier.windowInsetsPadding(WindowInsets.safeDrawing) सभी चार किनारों पर पैडिंग के तौर पर, सेफ़ ड्रॉइंग इनसेट लागू करता है.

सबसे ज़्यादा इस्तेमाल किए जाने वाले इंसर्ट टाइप के लिए, कई यूटिलिटी मेथड भी पहले से मौजूद हैं. Modifier.safeDrawingPadding() ऐसा ही एक तरीका है, जो Modifier.windowInsetsPadding(WindowInsets.safeDrawing) के बराबर है. अन्य इंसर्ट टाइप के लिए, मिलते-जुलते मॉडिफ़ायर मौजूद हैं.

इंसर्ट साइज़ मॉडिफ़ायर

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

Modifier.windowInsetsStartWidth(windowInsets: WindowInsets)

windowInsets के शुरुआती हिस्से को चौड़ाई के तौर पर लागू करता है (जैसे, Modifier.width)

Modifier.windowInsetsEndWidth(windowInsets: WindowInsets)

windowInsets के आखिर वाले हिस्से को चौड़ाई के तौर पर लागू करता है (जैसे कि Modifier.width)

Modifier.windowInsetsTopHeight(windowInsets: WindowInsets)

windowInsets के सबसे ऊपर वाले हिस्से को ऊंचाई के तौर पर इस्तेमाल करता है (जैसे, Modifier.height)

Modifier.windowInsetsBottomHeight(windowInsets: WindowInsets)

windowInsets के सबसे नीचे वाले हिस्से को ऊंचाई के तौर पर लागू करता है (जैसे, Modifier.height)

ये मॉडिफ़ायर, खास तौर पर ऐसे Spacer का साइज़ तय करने के लिए काम आते हैं जो इनसेट की जगह लेते हैं:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

इनसेट का इस्तेमाल

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

इन्सर्ट के साइज़ में बदलाव करने वाले फ़ंक्शन भी, इंसर्ट के एक ही हिस्से का इस्तेमाल एक से ज़्यादा बार नहीं करते. ऐसा तब होता है, जब इंसर्ट का इस्तेमाल पहले ही किया जा चुका हो. हालांकि, ये सीधे तौर पर अपना साइज़ बदलते हैं, इसलिए ये इनसेट का इस्तेमाल नहीं करते.

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

यहां LazyColumnLazyColumn के साइज़ को imePadding मॉडिफ़ायर की मदद से बदला जा रहा है. LazyColumn के अंदर, आखिरी आइटम को सिस्टम बार के सबसे निचले हिस्से की ऊंचाई के हिसाब से साइज़ किया जाता है:

LazyColumn(
    Modifier.imePadding()
) {
    // Other content
    item {
        Spacer(
            Modifier.windowInsetsBottomHeight(
                WindowInsets.systemBars
            )
        )
    }
}

IME बंद होने पर, imePadding() में कोई पैडिंग नहीं होती है. इसलिए, कोई भी इनसेट इस्तेमाल नहीं किया जाता है. साथ ही, Spacer की ऊंचाई, सिस्टम के सबसे नीचे मौजूद बार से मेल खाती है.

IME खुलने पर, IME इनसेट, IME के साइज़ के हिसाब से ऐनिमेट होते हैं. साथ ही, IME खुलने पर imePadding() मॉडिफ़ायर, LazyColumn का साइज़ बदलने के लिए बॉटम पैडिंग लागू करना शुरू कर देता है. imePadding() मॉडिफ़ायर, बॉटम पैडिंग लागू करना शुरू करता है. साथ ही, यह इनसेट की उस मात्रा का इस्तेमाल करना भी शुरू कर देता है. इसलिए, Spacer की ऊंचाई कम होने लगती है, क्योंकि सिस्टम बार के लिए स्पेसिंग का हिस्सा, imePadding() मॉडिफ़ायर पहले ही लागू कर चुका है. जब imePadding() मॉडिफ़ायर, सिस्टम बार से ज़्यादा बॉटम पैडिंग लागू करता है, तब Spacer की ऊंचाई शून्य होती है.

जब IME बंद होता है, तो बदलाव उल्टे क्रम में होते हैं: Spacer की ऊंचाई शून्य से बढ़ती है, क्योंकि imePadding(), सिस्टम बार के नीचे वाले हिस्से पर कम लागू होता है. आखिर में, 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 के चरणों के साथ खास संबंध होता है.

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