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

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

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

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

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

    enableEdgeToEdge()

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

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

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

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

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

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

आम तौर पर इस्तेमाल होने वाले इनसेट टाइप के लिए, पहले से मौजूद कई यूटिलिटी तरीके भी उपलब्ध हैं. Modifier.safeDrawingPadding() ऐसा ही एक तरीका है, जो Modifier.windowInsetsPadding(WindowInsets.safeDrawing) के बराबर है. यहां दी गई टेबल में, पहले से मौजूद पैडिंग मॉडिफ़ायर और हर एक पर लागू होने वाले WindowInsets टाइप की सूची दी गई है:

Modifier.safeDrawingPadding()

WindowInsets.safeDrawing

Modifier.safeGesturesPadding()

WindowInsets.safeGestures

Modifier.safeContentPadding()

WindowInsets.safeContent

Modifier.statusBarsPadding()

WindowInsets.statusBars

Modifier.navigationBarsPadding()

WindowInsets.navigationBars

Modifier.captionBarPadding()

WindowInsets.captionBar

Modifier.systemBarsPadding()

WindowInsets.systemBars

Modifier.imePadding()

WindowInsets.ime

Modifier.systemGesturesPadding()

WindowInsets.systemGestures

Modifier.mandatorySystemGesturesPadding()

WindowInsets.mandatorySystemGestures

Modifier.displayCutoutPadding()

WindowInsets.displayCutout

Modifier.waterfallPadding()

WindowInsets.waterfall

हर तरह के इनसेट में क्या शामिल होता है, यह जानने के लिए विंडो इनसेट के बारे में जानकारी देखें.

इनसेट साइज़ मॉडिफ़ायर

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

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 जैसे हेल्पर), इनसेट के उस हिस्से को अपने-आप इस्तेमाल कर लेते हैं जिसे पैडिंग के तौर पर लागू किया जाता है. कंपोज़िशन ट्री में गहराई से जाने पर, नेस्ट किए गए इनसेट पैडिंग मॉडिफ़ायर और इनसेट साइज़ मॉडिफ़ायर को पता चलता है कि इनसेट का कुछ हिस्सा, बाहरी इनसेट पैडिंग मॉडिफ़ायर पहले ही इस्तेमाल कर चुके हैं. साथ ही, इनसेट के उसी हिस्से को एक से ज़्यादा बार इस्तेमाल करने से बचा जाता है. इससे बहुत ज़्यादा अतिरिक्त जगह बच जाती है.

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

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

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

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

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

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

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

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