রচনা লেআউটে অন্তর্নিহিত পরিমাপ

Compose-এর একটি নিয়ম হলো, আপনার চাইল্ড ভেরিয়েবলগুলোকে শুধুমাত্র একবারই মেজার করা উচিত; চাইল্ড ভেরিয়েবলগুলোকে দুইবার মেজার করলে একটি রানটাইম এক্সেপশন দেখা দেয়। তবে, এমন অনেক সময় আসে যখন চাইল্ড ভেরিয়েবলগুলোকে মেজার করার আগেই তাদের সম্পর্কে কিছু তথ্যের প্রয়োজন হয়।

ইন্ট্রিনসিকস আপনাকে চাইল্ড ডেটা পরিমাপ করার আগেই কোয়েরি করার সুযোগ দেয়।

একটি কম্পোজেবলের জন্য, আপনি এর IntrinsicSize.Min বা IntrinsicSize.Max জানতে চাইতে পারেন:

  • Modifier.width(IntrinsicSize.Min) - আপনার কন্টেন্ট সঠিকভাবে প্রদর্শন করার জন্য সর্বনিম্ন কত প্রস্থ প্রয়োজন?
  • Modifier.width(IntrinsicSize.Max) - আপনার কন্টেন্ট সঠিকভাবে প্রদর্শন করার জন্য সর্বোচ্চ কত প্রস্থ প্রয়োজন?
  • Modifier.height(IntrinsicSize.Min) - আপনার কন্টেন্ট সঠিকভাবে প্রদর্শন করার জন্য সর্বনিম্ন উচ্চতা কত হওয়া প্রয়োজন?
  • Modifier.height(IntrinsicSize.Max) - আপনার কন্টেন্ট সঠিকভাবে প্রদর্শন করার জন্য সর্বোচ্চ কত উচ্চতা প্রয়োজন?

উদাহরণস্বরূপ, যদি আপনি একটি কাস্টম লেআউটে অসীম width সীমাবদ্ধতাযুক্ত কোনো Text minIntrinsicHeight জানতে চান, তাহলে এটি Text সেই height ফেরত দেবে যেখানে লেখাটি এক লাইনে আঁকা আছে।

ইন্ট্রিনসিকস ইন অ্যাকশন

আপনি এমন একটি কম্পোজেবল তৈরি করতে পারেন যা একটি ডিভাইডার দ্বারা পৃথক করা দুটি টেক্সট স্ক্রিনে প্রদর্শন করে:

পাশাপাশি দুটি টেক্সট এলিমেন্ট, এবং তাদের মাঝে একটি উল্লম্ব বিভাজক রয়েছে।

এটি করার জন্য, একটি Row ব্যবহার করুন যেখানে দুটি Text composable থাকবে যা উপলব্ধ স্থানটি পূরণ করবে, এবং মাঝখানে একটি DividerDivider টির উচ্চতা সবচেয়ে লম্বা Text সমান এবং এটি পাতলা ( width = 1.dp ) হওয়া উচিত।

@Composable
fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) {
    Row(modifier = modifier) {
        Text(
            modifier = Modifier
                .weight(1f)
                .padding(start = 4.dp)
                .wrapContentWidth(Alignment.Start),
            text = text1
        )
        VerticalDivider(
            color = Color.Black,
            modifier = Modifier.fillMaxHeight().width(1.dp)
        )
        Text(
            modifier = Modifier
                .weight(1f)
                .padding(end = 4.dp)
                .wrapContentWidth(Alignment.End),

            text = text2
        )
    }
}

Divider পুরো স্ক্রিন জুড়ে প্রসারিত হয়, যা কাঙ্ক্ষিত আচরণ নয়:

পাশাপাশি দুটি টেক্সট এলিমেন্ট, তাদের মাঝে একটি ডিভাইডার রয়েছে, কিন্তু ডিভাইডারটি টেক্সটের নীচের অংশ পর্যন্ত বিস্তৃত।

এর কারণ হলো, Row প্রতিটি চাইল্ডকে আলাদাভাবে পরিমাপ করে এবং Divider সীমাবদ্ধ করতে Text এর উচ্চতা ব্যবহার করা যায় না।

এর পরিবর্তে, Divider একটি নির্দিষ্ট উচ্চতায় উপলব্ধ স্থান পূরণ করাতে, height(IntrinsicSize.Min) মডিফায়ারটি ব্যবহার করুন।

height(IntrinsicSize.Min) এর চাইল্ডগুলোকে তাদের সর্বনিম্ন ইন্ট্রিনসিক হাইটের সমান লম্বা করে। যেহেতু এই মডিফায়ারটি রিকার্সিভ, তাই এটি Row এবং এর চাইল্ডগুলোর minIntrinsicHeight কোয়েরি করে।

আপনার কোডে এই মডিফায়ারটি প্রয়োগ করলে তা প্রত্যাশিতভাবে কাজ করবে:

@Composable
fun TwoTexts(modifier: Modifier = Modifier, text1: String, text2: String) {
    Row(modifier = modifier.height(IntrinsicSize.Min)) {
        Text(
            modifier = Modifier
                .weight(1f)
                .padding(start = 4.dp)
                .wrapContentWidth(Alignment.Start),
            text = text1
        )
        VerticalDivider(
            color = Color.Black,
            modifier = Modifier.fillMaxHeight().width(1.dp)
        )
        Text(
            modifier = Modifier
                .weight(1f)
                .padding(end = 4.dp)
                .wrapContentWidth(Alignment.End),

            text = text2
        )
    }
}

// @Preview
@Composable
fun TwoTextsPreview() {
    MaterialTheme {
        Surface {
            TwoTexts(text1 = "Hi", text2 = "there")
        }
    }
}

প্রিভিউ সহ:

পাশাপাশি দুটি টেক্সট এলিমেন্ট, এবং তাদের মাঝে একটি উল্লম্ব বিভাজক রয়েছে।

Row উচ্চতা নিম্নরূপে নির্ধারণ করা হয়:

  • Row composable-এর minIntrinsicHeight হলো এর চাইল্ডগুলোর মধ্যে সর্বোচ্চ minIntrinsicHeight
  • Divider এলিমেন্টটির minIntrinsicHeight হলো 0, কারণ কোনো সীমাবদ্ধতা না দেওয়া থাকলে এটি কোনো জায়গা দখল করে না।
  • minIntrinsicHeight হলো একটি নির্দিষ্ট width জন্য Text উচ্চতা।
  • সুতরাং, Row এলিমেন্টের height সীমাবদ্ধতাটি Text গুলোর সর্বোচ্চ minIntrinsicHeight হয়ে যায়।
  • এরপর Divider Row দ্বারা প্রদত্ত height সীমাবদ্ধতা অনুযায়ী তার height প্রসারিত করে।

আপনার কাস্টম লেআউটের অন্তর্নিহিত বিষয়গুলি

কাস্টম Layout বা layout মডিফায়ার তৈরি করার সময়, আনুমানিক হিসাবের উপর ভিত্তি করে অন্তর্নিহিত পরিমাপ স্বয়ংক্রিয়ভাবে গণনা করা হয়। তাই, এই গণনা সব লেআউটের জন্য সঠিক নাও হতে পারে। এই এপিআইগুলো এই ডিফল্ট মানগুলোকে ওভাররাইড করার বিকল্প প্রদান করে।

আপনার কাস্টম Layout ইন্ট্রিনসিক পরিমাপ নির্দিষ্ট করতে, এটি তৈরি করার সময় MeasurePolicy ইন্টারফেসের minIntrinsicWidth , minIntrinsicHeight , maxIntrinsicWidth এবং maxIntrinsicHeight ওভাররাইড করুন।

@Composable
fun MyCustomComposable(
    modifier: Modifier = Modifier,
    content: @Composable () -> Unit
) {
    Layout(
        content = content,
        modifier = modifier,
        measurePolicy = object : MeasurePolicy {
            override fun MeasureScope.measure(
                measurables: List<Measurable>,
                constraints: Constraints
            ): MeasureResult {
                // Measure and layout here
                // ...
            }

            override fun IntrinsicMeasureScope.minIntrinsicWidth(
                measurables: List<IntrinsicMeasurable>,
                height: Int
            ): Int {
                // Logic here
                // ...
            }

            // Other intrinsics related methods have a default value,
            // you can override only the methods that you need.
        }
    )
}

আপনার কাস্টম layout মডিফায়ার তৈরি করার সময়, LayoutModifier ইন্টারফেসের সংশ্লিষ্ট মেথডগুলো ওভাররাইড করুন।

fun Modifier.myCustomModifier(/* ... */) = this then object : LayoutModifier {

    override fun MeasureScope.measure(
        measurable: Measurable,
        constraints: Constraints
    ): MeasureResult {
        // Measure and layout here
        // ...
    }

    override fun IntrinsicMeasureScope.minIntrinsicWidth(
        measurable: IntrinsicMeasurable,
        height: Int
    ): Int {
        // Logic here
        // ...
    }

    // Other intrinsics related methods have a default value,
    // you can override only the methods that you need.
}

{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}