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

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

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

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

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

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

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

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

IME बंद होने पर, बदलाव उल्टे क्रम में होते हैं: Spacer की ऊंचाई शून्य से बढ़ने लगती है. ऐसा तब होता है, जब imePadding(), सिस्टम बार के निचले हिस्से से कम जगह लेता है. आखिर में, Spacer की ऊंचाई, सिस्टम बार के निचले हिस्से की ऊंचाई के बराबर हो जाती है. ऐसा तब होता है, जब IME पूरी तरह से ऐनिमेट हो जाता है.

दूसरी इमेज. 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 के फ़ेज़ के साथ खास संबंध होता है.

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