یکی از قوانین Compose این است که باید فرزندان خود را فقط یک بار اندازهگیری کنید؛ اندازهگیری فرزندان دو بار یک استثنای زمان اجرا ایجاد میکند. اما گاهی اوقات پیشاز اندازهگیری کودکان، به اطلاعاتی درباره آنها نیاز دارید.
Intrinsics به شما امکان میدهد قبلاز اندازهگیری واقعی فرزندان، از آنها پرسوجو کنید.
برای یک composable، میتوانید IntrinsicSize.Min یا IntrinsicSize.Max آن را درخواست کنید:
Modifier.width(IntrinsicSize.Min)- حداقل عرضی که برای نمایش درست محتوایتان نیاز دارید چقدر است؟Modifier.width(IntrinsicSize.Max)- حداکثر عرضی که برای نمایش درست محتوایتان نیاز دارید چقدر است؟Modifier.height(IntrinsicSize.Min)- حداقل ارتفاعی که برای نمایش درست محتوایتان نیاز دارید چقدر است؟Modifier.height(IntrinsicSize.Max)- حداکثر ارتفاعی که برای نمایش درست محتوایتان نیاز دارید چقدر است؟
برای مثال، اگر minIntrinsicHeight Text را با محدودیتهای بینهایت
width در چیدمان سفارشی درخواست کنید، height Text را
با نوشتار ترسیمشده در یک خط برمیگرداند.
Intrinsics در عمل
میتوانید یک composable ایجاد کنید که دو نوشتار را روی صفحه نمایش دهد که با یک جداکننده از هم جدا شدهاند:
برای انجام این کار، از Row با دو Text ترکیبپذیر که فضای دردسترس را پر میکنند، و 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) اندازه فرزندانش را بهاندازه حداقل ارتفاع ذاتیشان تعیین میکند. چون این اصلاحکننده بازگشتی است،
minIntrinsicHeight مربوط به Row و فرزندان آن را پرسمان میکند.
اعمال این اصلاحکننده به کدتان باعث میشود طبق انتظار کار کند:
@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 بهصورت زیر تعیین میشود:
minIntrinsicHeightترکیبپذیرRowحداکثرminIntrinsicHeightفرزندان آن است.minIntrinsicHeightعنصرDividerبرابر با ۰ است، زیرا اگر هیچ محدودیتی داده نشود، فضایی را اشغال نمیکند.TextminIntrinsicHeightمربوط به نوشتار برایwidthخاصی است.- بنابراین، محدودیت
heightعنصرRowبه حداکثرminIntrinsicHeightTextتبدیل میشود. - سپس
Dividerheightخود را به محدودیتheightارائهشده توسطRowگسترش میدهد.
ویژگیهای ذاتی در چیدمانهای سفارشی شما
هنگام ایجاد اصلاحکننده سفارشی Layout یا layout، اندازهگیریهای ذاتی
بهطور خودکار براساس تقریبها محاسبه میشوند. بنابراین، ممکن است محاسبات برای همه چیدمانها درست نباشد. این میاناهای برنامهسازی کاربردی گزینههایی
برای لغو این پیشفرضها ارائه میدهند.
برای مشخص کردن اندازهگیریهای ذاتی Layout سفارشیتان،
minIntrinsicWidth، minIntrinsicHeight، maxIntrinsicWidth، و
maxIntrinsicHeight میانای MeasurePolicy را هنگام ایجاد آن لغو کنید.
@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. }
توصیهشده برای شما
- توجه: وقتی جاوا اسکریپت خاموش باشد، نوشتار پیوند نمایش داده میشود
- چیدمانهای سفارشی {:#custom-layouts}
- خطوط تراز در Jetpack Compose
- فازهای Jetpack Compose