উইন্ডো ইনসেট সেট-আপ করা

আপনার অ্যাক্টিভিটি সব ইনসেট ম্যানেজ করার কন্ট্রোল নিয়ে নিলে, আপনি Compose API ব্যবহার করে যাচাই করতে পারবেন যে কন্টেন্ট অস্পষ্ট নয় এবং ইন্টার‍্যাক্ট করা যায় এমন এলিমেন্ট সিস্টেম UI-এর সাথে ওভারল্যাপ করছে না। এছাড়াও, এই API আপনার অ্যাপের লেআউট ইনসেট পরিবর্তনের সাথে সিঙ্ক করে।

প্যাডিং বা সাইজ মডিফায়ার ব্যবহার করে ইনসেট ম্যানেজ করুন

যেমন, আপনার সম্পূর্ণ অ্যাপের কন্টেন্টে ইনসেট প্রয়োগ করার সবচেয়ে প্রাথমিক পদ্ধতি হল এটি:

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

    enableEdgeToEdge()

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

এই স্নিপেট অ্যাপের সম্পূর্ণ কন্টেন্টের চারপাশে প্যাডিং হিসেবে safeDrawing উইন্ডো ইনসেট প্রয়োগ করে। এটি যেমন নিশ্চিত করে যে ইন্টার‍্যাক্ট করা যায় এমন এলিমেন্ট সিস্টেম UI-এর সাথে ওভারল্যাপ করবে না, তেমনই এর অর্থ হল, এজ-টু-এজ এফেক্ট পাওয়ার জন্য অ্যাপের কোনও অংশ সিস্টেম UI-এর পিছনে ড্র করবে না। পুরো উইন্ডোটি সম্পূর্ণভাবে ব্যবহার করতে, আপনাকে স্ক্রিন-বাই-স্ক্রিন বা কম্পোনেন্ট-বাই-কম্পোনেন্ট ভিত্তিতে ইনসেটগুলি কোথায় প্রয়োগ করা হয়েছে তা ফাইন-টিউন করতে হবে।

এইসব ইনসেটের ধরন API 21-এ ব্যাকপোর্ট করা IME অ্যানিমেশনের মাধ্যমে অটোমেটিক অ্যানিমেট করা হয়। এছাড়াও, এই ইনসেট ব্যবহার করা আপনার সব লেআউটও ইনসেট ভ্যালু পরিবর্তন হওয়ার সাথে সাথে অটোমেটিক অ্যানিমেট হয়ে যায়।

আপনার কম্পোজেবল লেআউট অ্যাডজাস্ট করার জন্য ইনসেট ম্যানেজ করার তিনটি উপায় আছে:

প্যাডিং মডিফায়ার

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
            )
        )
    }
}

IME বন্ধ থাকলে, imePadding() কোনও প্যাডিং প্রয়োগ করে না। ফলস্বরূপ, কোনও ইনসেট ব্যবহার করা হয় না এবং Spacer-এর উচ্চতা নিচের সিস্টেম বারের সাথে মিলে যায়।

IME খুললে, IME-এর সাইজের সাথে ম্যাচ করার জন্য IME ইনসেট অ্যানিমেট করে এবং imePadding() মডিফায়ার, IME খোলার সাথে সাথে 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 ভ্যালু ব্যবহার করুন অথবা কনজাম্পশনের মাধ্যমে প্রভাবিত হয়নি এমন ইনসেটের PaddingValues রিটার্ন করতে WindowInsets.asPaddingValues() ব্যবহার করুন। তবে, নিম্নলিখিত সতর্কতাগুলির কারণে, যেখানেই সম্ভব উইন্ডো ইনসেট প্যাডিং মডিফায়ার এবং উইন্ডো ইনসেট সাইজ মডিফায়ার ব্যবহার করতে পছন্দ করুন।

ইনসেট ও Jetpack Compose-এর ফেজ

ইনসেট আপডেট ও অ্যানিমেট করতে Compose অন্তর্নিহিত AndroidX কোর API ব্যবহার করে, যা ইনসেট ম্যানেজ করার জন্য অন্তর্নিহিত প্ল্যাটফর্ম API ব্যবহার করে। প্ল্যাটফর্মের সেই আচরণের কারণে, ইনসেটের সাথে Jetpack Compose-এর ফেজ-এর বিশেষ সম্পর্ক আছে।

ইনসেটের ভ্যালু কম্পোজিশন ফেজের পরে, কিন্তু লেআউট ফেজের আগে আপডেট করা হয়। এর অর্থ হল, কম্পোজিশনে ইনসেটের ভ্যালু রিড করার সময় সাধারণত ইনসেটের এমন ভ্যালু ব্যবহার করা হয় যা এক ফ্রেম পরে আসে। এই পৃষ্ঠায় বর্ণিত বিল্ট-ইন মডিফায়ারগুলি লেআউট ফেজ পর্যন্ত ইনসেটের ভ্যালু ব্যবহার করতে দেরি করার জন্য তৈরি করা হয়েছে, যা নিশ্চিত করে যে ইনসেট ভ্যালুগুলি আপডেট হওয়ার সাথে সাথে একই ফ্রেমে ব্যবহার করা হয়।