Compose-এর একটি নিয়ম হল, আপনাকে চাইল্ড কম্পোজেবল একবারই পরিমাপ করতে হবে; চাইল্ড কম্পোজেবল দুবার পরিমাপ করলে রানটাইম এক্সেপশন থ্রো করে। তবে, এমন কিছু সময় আসে যখন আপনার সন্তানের উচ্চতা পরিমাপ করার আগে তার সম্পর্কে কিছু তথ্য প্রয়োজন হয়।
Intrinsics আপনাকে চিলড্রেনকে কোয়েরি করতে দেয়, তাদের আসলে পরিমাপ করার আগে।
কম্পোজেবলকে আপনি 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 ফিরিয়ে দেয়।
ইন্ট্রিনসিক্স ইন অ্যাকশন
আপনি এমন একটি কম্পোজেবল তৈরি করতে পারেন যা স্ক্রিনে দুটি টেক্সট দেখায় এবং সেগুলি একটি ডিভাইডার দিয়ে আলাদা করা থাকে:
এটি করতে, দুটি Text কম্পোজেবল সহ একটি Row ব্যবহার করুন যা উপলভ্য জায়গা পূরণ করে এবং
মাঝখানে একটি Divider থাকে। Divider-এর উচ্চতা সবচেয়ে লম্বা 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 প্রতিটি চাইল্ডকে আলাদাভাবে পরিমাপ করে এবং Text-এর উচ্চতা
Divider-কে সীমাবদ্ধ করতে ব্যবহার করা যাবে না।
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কম্পোজেবলেরminIntrinsicHeightহল এর চিলড্রেনের সর্বাধিকminIntrinsicHeight।Dividerএলিমেন্টেরminIntrinsicHeightহল ০, কারণ কোনও সীমাবদ্ধতা না থাকলে এটি জায়গা দখল করে না।TextminIntrinsicHeightহল নির্দিষ্টwidth-এর জন্য টেক্সটের।- তাই,
Rowএলিমেন্টেরheightকনস্ট্রেন্টText-এর সর্বাধিকminIntrinsicHeightহয়ে যায়। DividerতারপরRow-এর দেওয়াheightসীমাবদ্ধতা অনুযায়ী তারheightপ্রসারিত করে।
আপনার কাস্টম লেআউটে ইন্ট্রিনসিক্স
কাস্টম Layout বা layout মডিফায়ার তৈরি করার সময়, আনুমানিক হিসেবের উপর ভিত্তি করে
ইন্ট্রিনসিক পরিমাপ অটোমেটিক গণনা করা হয়। তাই, সব লেআউটের জন্য গণনা সঠিক নাও হতে পারে। এইসব API, ডিফল্ট সেটিংস ওভাররাইড করার
বিকল্প অফার করে।
আপনার কাস্টম Layout-এর ইন্ট্রিনসিক পরিমাপ নির্দিষ্ট করতে,
minIntrinsicWidth, minIntrinsicHeight, maxIntrinsicWidth এবং
maxIntrinsicHeight ওভাররাইড করুন, যখন MeasurePolicy ইন্টারফেস তৈরি করছেন।
আপনার ওভাররাইডকে measure-এর সাথে ম্যাচ করতে হবে। যেমন, একটি কাস্টম
কলামে যা তার চাইল্ডকে উল্লম্বভাবে স্ট্যাক করে এবং প্রতিটি চাইল্ডকে সম্পূর্ণ কলামের
প্রস্থ দেয়, প্রদত্ত width-এর জন্য ন্যূনতম অন্তর্নিহিত উচ্চতা হল সেই width-এর জন্য তার
চাইল্ডের ন্যূনতম অন্তর্নিহিত উচ্চতার যোগফল:
@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 { val childConstraints = constraints.copy(minHeight = 0) val placeables = measurables.map { measurable -> measurable.measure(childConstraints) } val width = constraints.constrainWidth( placeables.maxOfOrNull { it.width } ?: 0 ) val height = constraints.constrainHeight( placeables.sumOf { it.height } ) return layout(width, height) { var yPosition = 0 placeables.forEach { placeable -> placeable.placeRelative(x = 0, y = yPosition) yPosition += placeable.height } } } override fun IntrinsicMeasureScope.minIntrinsicHeight( measurables: List<IntrinsicMeasurable>, width: Int ): Int { return measurables.sumOf { measurable -> measurable.minIntrinsicHeight(width) } } // Other intrinsics related methods have a default value, // you can override only the methods that you need. } ) }
আপনার কাস্টম layout মডিফায়ার তৈরি করার সময়, LayoutModifier ইন্টারফেসে
সম্পর্কিত পদ্ধতি ওভাররাইড করুন। ইন্ট্রিনসিক ক্যালকুলেশন
measure-এর সাথে মিলতে হবে। যেমন, কোনও প্রদত্ত height-এর জন্য, একটি মডিফায়ার যা সব দিকে নির্দিষ্ট প্যাডিং যোগ করে,
চাইল্ডের minIntrinsicWidth কোয়েরি করার আগে উল্লম্ব প্যাডিং বিয়োগ করে
এবং ফলাফলে অনুভূমিক প্যাডিং যোগ করে:
fun Modifier.myCustomModifier(padding: Dp = 8.dp) = this then object : LayoutModifier { override fun MeasureScope.measure( measurable: Measurable, constraints: Constraints ): MeasureResult { val paddingPx = padding.roundToPx() val horizontal = paddingPx * 2 val vertical = paddingPx * 2 val placeable = measurable.measure( constraints.offset(-horizontal, -vertical) ) val width = constraints.constrainWidth(placeable.width + horizontal) val height = constraints.constrainHeight(placeable.height + vertical) return layout(width, height) { placeable.place(paddingPx, paddingPx) } } override fun IntrinsicMeasureScope.minIntrinsicWidth( measurable: IntrinsicMeasurable, height: Int ): Int { val paddingPx = padding.roundToPx() val horizontal = paddingPx * 2 val vertical = paddingPx * 2 val childHeight = if (height == Constraints.Infinity) { Constraints.Infinity } else { (height - vertical).coerceAtLeast(0) } return measurable.minIntrinsicWidth(childHeight) + horizontal } // Other intrinsics related methods have a default value, // you can override only the methods that you need. }
আপনার জন্য সাজেস্ট করা হয়েছে
- মনে রাখবেন: জাভাস্ক্রিপ্ট বন্ধ থাকলে লিঙ্ক টেক্সট দেখানো হয়
- কাস্টম লেআউট {:#custom-layouts}
- Jetpack Compose-এ অ্যালাইনমেন্ট লাইন
- Jetpack Compose-এর পর্যায়