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

একবার আপনার অ্যাক্টিভিটি সমস্ত ইনসেট পরিচালনার দায়িত্ব নিয়ে নিলে, আপনি কম্পোজ এপিআই (Compose APIs) ব্যবহার করে যাচাই করতে পারেন যে কন্টেন্ট ঢাকা পড়ছে না এবং ইন্টারেক্টেবল এলিমেন্টগুলো সিস্টেম ইউআই (UI)-এর সাথে ওভারল্যাপ করছে না। এই এপিআইগুলো ইনসেট পরিবর্তনের সাথে আপনার অ্যাপের লেআউটকেও সিনক্রোনাইজ করে।

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

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

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

    enableEdgeToEdge()

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

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

এপিআই ২১-এ ব্যাকপোর্ট করা আইএমই অ্যানিমেশনের মাধ্যমে এই সব ধরনের ইনসেট স্বয়ংক্রিয়ভাবে অ্যানিমেট হয়। এর ফলস্বরূপ, ইনসেটের মান পরিবর্তনের সাথে সাথে এই ইনসেটগুলো ব্যবহারকারী আপনার সমস্ত লেআউটও স্বয়ংক্রিয়ভাবে অ্যানিমেট হয়ে যায়।

আপনার কম্পোজেবল লেআউটগুলো সামঞ্জস্য করতে ইনসেটগুলো পরিচালনা করার তিনটি উপায় রয়েছে:

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

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 উদাহরণটির দিকে তাকালে দেখা যায়, LazyColumn টিকে imePadding মডিফায়ারের মাধ্যমে রিসাইজ করা হচ্ছে। LazyColumn এর ভেতরে, শেষ আইটেমটির সাইজ সিস্টেম বারের নিচের অংশের উচ্চতার সমান করা হয়েছে:

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

যখন IME বন্ধ থাকে, তখন imePadding() মডিফায়ার কোনো প্যাডিং প্রয়োগ করে না, কারণ IME-এর কোনো উচ্চতা নেই। যেহেতু imePadding() মডিফায়ার কোনো প্যাডিং প্রয়োগ করছে না, তাই কোনো ইনসেট ব্যবহৃত হয় না, এবং Spacer উচ্চতা সিস্টেম বারের নিচের দিকের আকারের সমান হবে।

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

ইনসেট এবং জেটপ্যাক কম্পোজ পর্যায়

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

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