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

আপনার অ্যাপটি কোথায় কন্টেন্ট আঁকবে তার উপর সম্পূর্ণ নিয়ন্ত্রণ রাখতে, এই সেটআপ ধাপগুলি অনুসরণ করুন। এই ধাপগুলি ছাড়া, আপনার অ্যাপটি সিস্টেম UI এর পিছনে কালো বা ঘন রঙ আঁকতে পারে, অথবা সফ্টওয়্যার কীবোর্ডের সাথে সিঙ্ক্রোনাসভাবে অ্যানিমেট নাও করতে পারে।

  1. Android 15 এবং তার পরবর্তী ভার্সনে এজ-টু-এজ প্রয়োগ করতে Android 15 (API লেভেল 35) বা তার পরবর্তী ভার্সনকে টার্গেট করুন। আপনার অ্যাপটি সিস্টেম UI এর পিছনে প্রদর্শিত হবে। আপনি ইনসেট পরিচালনা করে আপনার অ্যাপের UI সামঞ্জস্য করতে পারেন।
  2. ঐচ্ছিকভাবে, Activity.onCreate()enableEdgeToEdge() কল করুন, যা আপনার অ্যাপটিকে পূর্ববর্তী অ্যান্ড্রয়েড সংস্করণগুলিতে এজ-টু-এজ করতে দেয়।
  3. আপনার Activity এর AndroidManifest.xml এন্ট্রিতে android:windowSoftInputMode="adjustResize" সেট করুন। এই সেটিংটি আপনার অ্যাপকে সফ্টওয়্যার IME এর আকার ইনসেট হিসাবে গ্রহণ করতে দেয়, যা আপনার অ্যাপে IME প্রদর্শিত এবং অদৃশ্য হয়ে গেলে উপযুক্ত লেআউট এবং প্যাডিং প্রয়োগ করতে সহায়তা করে।

    <!-- In your AndroidManifest.xml file: -->
    <activity
      android:name=".ui.MainActivity"
      android:label="@string/app_name"
      android:windowSoftInputMode="adjustResize"
      android:theme="@style/Theme.MyApplication"
      android:exported="true">
    
  4. ইনসেটগুলি পরিচালনা করুন যাতে আপনার গুরুত্বপূর্ণ UI সিস্টেম বার বা ডিসপ্লে কাটআউটের সাথে ওভারল্যাপ না করে। আপনি রুলার , প্যাডিং মডিফায়ার বা ইনসেট সাইজ মডিফায়ার ব্যবহার করে ইনসেটগুলি পরিচালনা করতে পারেন। কিছু ম্যাটেরিয়াল কম্পোনেন্ট স্বয়ংক্রিয়ভাবে ইনসেটগুলি পরিচালনা করে অথবা Scaffold এর PaddingValues ​​প্যারামিটারের মতো ইনসেটগুলি পরিচালনা করার সুবিধার্থে প্যারামিটার থাকে। একটি ইনসেট হ্যান্ডলিং পদ্ধতি বেছে নিন। উদাহরণস্বরূপ, Scaffold , Modifier.safeDrawingPadding() , অথবা Modifier.fitInside(WindowInsetsRulers.SafeDrawing.current) ব্যবহার করুন কারণ এই পদ্ধতিগুলি প্রায়শই বিনিময়যোগ্য।

প্যাডিং বা আকার পরিবর্তনকারী ব্যবহার করে ইনসেটগুলি পরিচালনা করুন

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

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

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) এর সমতুল্য। অন্যান্য ইনসেট ধরণের জন্য অনুরূপ মডিফায়ার রয়েছে।

ইনসেট আকার পরিবর্তনকারী

নিম্নলিখিত সংশোধকগুলি উপাদানের আকারকে ইনসেটের আকার হিসাবে সেট করে উইন্ডো ইনসেটের পরিমাণ প্রয়োগ করে:

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

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

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

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