WindowInsetsRulers সম্পর্কে

WindowInsets হল Jetpack Compose-এর স্ট্যান্ডার্ড API যা স্ক্রিনের সেই অংশগুলি পরিচালনা করে যা সিস্টেম UI দ্বারা আংশিক বা সম্পূর্ণরূপে অস্পষ্ট থাকে। এই অংশগুলির মধ্যে রয়েছে স্ট্যাটাস বার, নেভিগেশন বার এবং অন-স্ক্রিন কীবোর্ড। আপনি বিকল্পভাবে পূর্বনির্ধারিত WindowInsetsRulers যেমন SafeDrawing কে Modifier.fitInside বা Modifier.fitOutside এ পাস করতে পারেন যাতে আপনার কন্টেন্ট সিস্টেম বার এবং ডিসপ্লে কাটআউটের সাথে সারিবদ্ধ হয় অথবা কাস্টম WindowInsetsRulers তৈরি করা যায়।

WindowInsetsRulers এর সুবিধা

  • খরচ জটিলতা এড়ায় : এটি লেআউটের প্লেসমেন্ট পর্যায়ে কাজ করে। এর অর্থ হল এটি ইনসেট খরচ শৃঙ্খলকে সম্পূর্ণরূপে বাইপাস করে এবং প্যারেন্ট লেআউটগুলি যা-ই করুক না কেন, সিস্টেম বার এবং ডিসপ্লে কাটআউটগুলির সঠিক, পরম অবস্থান সর্বদা প্রদান করতে পারে। যখন পূর্বপুরুষ কম্পোজেবলগুলি ভুলভাবে ইনসেট ব্যবহার করে তখন Modifier.fitInside বা Modifier.fitOutside পদ্ধতি ব্যবহার করা সমস্যা সমাধানে সহায়ক।
  • সিস্টেম বারগুলি সহজেই এড়িয়ে চলুন : এটি আপনার অ্যাপের কন্টেন্টগুলিকে সিস্টেম বার এবং ডিসপ্লে কাটআউট এড়াতে সাহায্য করে এবং এটি সরাসরি WindowInsets ব্যবহারের চেয়ে আরও সহজ হতে পারে।
  • অত্যন্ত কাস্টমাইজেবল : ডেভেলপাররা কাস্টম রুলারের সাথে কন্টেন্ট সারিবদ্ধ করতে পারে এবং কাস্টম লেআউটের মাধ্যমে তাদের লেআউটের উপর সুনির্দিষ্ট নিয়ন্ত্রণ রাখতে পারে।

WindowInsetsRulers এর অসুবিধাগুলি

  • পরিমাপের জন্য ব্যবহার করা যাবে না : যেহেতু এটি স্থান নির্ধারণের পর্যায়ে কাজ করে, তাই এটি যে অবস্থানগত তথ্য প্রদান করে তা পূর্ববর্তী পরিমাপ পর্যায়ে পাওয়া যায় না

আপনার কন্টেন্টকে মডিফায়ার পদ্ধতির সাথে সারিবদ্ধ করুন

Modifier.fitInside অ্যাপগুলিকে সিস্টেম বারের সাথে কন্টেন্ট সারিবদ্ধ করতে এবং কাটআউট প্রদর্শন করতে দেয়। এটি WindowInsets এর পরিবর্তে ব্যবহার করা যেতে পারে। Modifier.fitOutside সাধারণত Modifier.fitInside এর বিপরীত হয়।

উদাহরণস্বরূপ, অ্যাপের কন্টেন্ট সিস্টেম বার এবং ডিসপ্লে কাটআউট এড়িয়ে চলে কিনা তা যাচাই করার জন্য, আপনি fitInside(WindowInsetsRulers.safeDrawing.current) ব্যবহার করতে পারেন।

@Composable
fun FitInsideDemo(modifier: Modifier) {
    Box(
        modifier = modifier
            .fillMaxSize()
            // Or DisplayCutout, Ime, NavigationBars, StatusBar, etc...
            .fitInside(WindowInsetsRulers.SafeDrawing.current)
    )
}

নিম্নলিখিত টেবিলটি দেখায় যে Modifier.fitInside অথবা Modifier.fitOutside ব্যবহার করে পূর্বনির্ধারিত রুলার ব্যবহার করলে আপনার অ্যাপের বিষয়বস্তু কেমন দেখাবে।

পূর্বনির্ধারিত রুলার টাইপ

Modifier.fitInside

Modifier.fitOutside

DisplayCutout

Ime

নিষিদ্ধ

NavigationBars

SafeDrawing

N/A (এর পরিবর্তে StatusBar , CaptionBar , NavigationBar ব্যবহার করুন)

StatusBar

Modifier.fitInside এবং Modifier.fitOutside ব্যবহার করার জন্য কম্পোজেবলগুলিকে সীমাবদ্ধ রাখতে হবে। এর অর্থ হল আপনাকে Modifier.size বা Modifier.fillMaxSize মতো মডিফায়ারগুলিকে সংজ্ঞায়িত করতে হবে।

কিছু রুলার যেমন Modifier.fitOutside on SafeDrawing এবং SystemBars একাধিক রুলার প্রদান করে। এই ক্ষেত্রে, Android বাম, উপরে, ডান, নীচে থেকে একটি রুলার ব্যবহার করে Composable স্থাপন করে।

Modifier.fitInside ব্যবহার করে IME এড়িয়ে চলুন

Modifier.fitInside সহ একটি IME দিয়ে নীচের উপাদানগুলি পরিচালনা করতে, একটি RectRuler পাস করুন যা NavigationBar এবং Ime এর সবচেয়ে ভেতরের মান নেয়।

@Composable
fun FitInsideWithImeDemo(modifier: Modifier) {
    Box(
        modifier = modifier
            .fillMaxSize()
            .fitInside(
                RectRulers.innermostOf(
                    WindowInsetsRulers.NavigationBars.current,
                    WindowInsetsRulers.Ime.current
                )
            )
    ) {
        TextField(
            value = "Demo IME Insets",
            onValueChange = {},
            modifier = modifier.align(Alignment.BottomStart).fillMaxWidth()
        )
    }
}

Modifier.fitInside ব্যবহার করে স্ট্যাটাস বার এবং ক্যাপশন বার এড়িয়ে চলুন

একইভাবে, শীর্ষ উপাদানগুলি যাচাই করার জন্য, Modifier.fitInsider এর সাথে স্ট্যাটাস বার এবং ক্যাপশন বার এড়িয়ে চলুন, একটি RectRuler পাস করুন যা StatusBars এবং CaptionBar এর সবচেয়ে ভেতরের মান নেয়।

@Composable
fun FitInsideWithStatusAndCaptionBarDemo(modifier: Modifier) {
    Box(
        modifier = modifier
            .fillMaxSize()
            .fitInside(
                RectRulers.innermostOf(
                    WindowInsetsRulers.StatusBars.current,
                    WindowInsetsRulers.CaptionBar.current
                )
            )
    )
}

কাস্টম WindowInsetsRulers তৈরি করুন

আপনি কাস্টম রুলারের সাথে কন্টেন্ট সারিবদ্ধ করতে পারেন। উদাহরণস্বরূপ, ব্যবহারের ক্ষেত্রে বিবেচনা করুন যেখানে একজন প্যারেন্ট কম্পোজেবল ভুলভাবে ইনসেটগুলি পরিচালনা করে যা ডাউনস্ট্রিম চাইল্ডে প্যাডিং সমস্যা সৃষ্টি করে। যদিও এই সমস্যাটি অন্যান্য উপায়ে সমাধান করা যেতে পারে, যার মধ্যে রয়েছে Modifier.fitInside ব্যবহার করে, আপনি নিম্নলিখিত উদাহরণ এবং ভিডিওতে দেখানো প্যারেন্ট আপস্ট্রিমে সমস্যাটি সমাধান না করেই চাইল্ড কম্পোজেবলকে সুনির্দিষ্টভাবে সারিবদ্ধ করার জন্য একটি কাস্টম রুলারও তৈরি করতে পারেন:

@Composable
fun WindowInsetsRulersDemo(modifier: Modifier) {
    Box(
        contentAlignment = BottomCenter,
        modifier = modifier
            .fillMaxSize()
            // The mistake that causes issues downstream, as .padding doesn't consume insets.
            // While it's correct to instead use .windowInsetsPadding(WindowInsets.navigationBars),
            // assume it's difficult to identify this issue to see how WindowInsetsRulers can help.
            .padding(WindowInsets.navigationBars.asPaddingValues())
    ) {
        TextField(
            value = "Demo IME Insets",
            onValueChange = {},
            modifier = modifier
                // Use alignToSafeDrawing() instead of .imePadding() to precisely place this child
                // Composable without having to fix the parent upstream.
                .alignToSafeDrawing()

            // .imePadding()
            // .fillMaxWidth()
        )
    }
}

fun Modifier.alignToSafeDrawing(): Modifier {
    return layout { measurable, constraints ->
        if (constraints.hasBoundedWidth && constraints.hasBoundedHeight) {
            val placeable = measurable.measure(constraints)
            val width = placeable.width
            val height = placeable.height
            layout(width, height) {
                val bottom = WindowInsetsRulers.SafeDrawing.current.bottom
                    .current(0f).roundToInt() - height
                val right = WindowInsetsRulers.SafeDrawing.current.right
                    .current(0f).roundToInt()
                val left = WindowInsetsRulers.SafeDrawing.current.left
                    .current(0f).roundToInt()
                measurable.measure(Constraints.fixed(right - left, height))
                    .place(left, bottom)
            }
        } else {
            val placeable = measurable.measure(constraints)
            layout(placeable.width, placeable.height) {
                placeable.place(0, 0)
            }
        }
    }
}

নিচের ভিডিওটিতে বাম দিকের ছবিতে একজন আপস্ট্রিম প্যারেন্টের কারণে সমস্যাযুক্ত IME ইনসেট ব্যবহারের একটি উদাহরণ দেখানো হয়েছে এবং ডানদিকে সমস্যাটি সমাধানের জন্য কাস্টম রুলার ব্যবহার করা হচ্ছে। নেভিগেশন বার প্যাডিংটি প্যারেন্ট দ্বারা ব্যবহার না করায় TextField কম্পোজেবলের নীচে অতিরিক্ত প্যাডিং দেখানো হয়েছে। পূর্ববর্তী কোড নমুনায় দেখানো একটি কাস্টম রুলার ব্যবহার করে শিশুটিকে সঠিক ছবিতে সঠিক স্থানে স্থাপন করা হয়েছে।

যাচাই করুন যে বাবা-মায়েরা বাধ্য।

নিরাপদে WindowInsetsRulers ব্যবহার করার জন্য, নিশ্চিত করুন যে অভিভাবক বৈধ সীমাবদ্ধতা প্রদান করেছেন। অভিভাবকদের একটি নির্দিষ্ট আকার থাকতে হবে এবং WindowInsetsRulers ব্যবহার করে এমন কোনও সন্তানের আকারের উপর নির্ভর করতে পারবেন না। প্যারেন্ট Composables-এ fillMaxSize বা অন্যান্য আকার পরিবর্তনকারী ব্যবহার করুন।

একইভাবে, verticalScroll এর মতো স্ক্রলিং কন্টেইনারের ভিতরে WindowInsetsRulers ব্যবহার করে এমন একটি কম্পোজেবল স্থাপন করলে অপ্রত্যাশিত আচরণ হতে পারে কারণ স্ক্রলিং কন্টেইনারটি সীমাহীন উচ্চতার সীমাবদ্ধতা প্রদান করে, যা রুলারের যুক্তির সাথে বেমানান।