یکی از قوانین 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 را با متن کشیده شده در یک خط واحد برمیگرداند.
عناصر ذاتی در عمل
شما میتوانید یک 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مربوط بهRowcomposable، حداکثرminIntrinsicHeightفرزندان آن است. -
minIntrinsicHeightعنصرDividerبرابر با ۰ است، زیرا اگر هیچ محدودیتی تعیین نشود، فضایی را اشغال نمیکند. -
minIntrinsicHeightText، مربوط به یکwidthخاص است. - بنابراین، قید
heightعنصرRowبه حداکثرminIntrinsicHeightمربوط بهTextتبدیل میشود. - سپس
Dividerheightخود را به محدودیتheightکه توسطRowداده شده است، افزایش میدهد.
ویژگیهای ذاتی در طرحبندیهای سفارشی شما
هنگام ایجاد یک Layout سفارشی یا اصلاحکننده layout ، اندازهگیریهای ذاتی به طور خودکار بر اساس تقریبها محاسبه میشوند. بنابراین، محاسبات ممکن است برای همه طرحبندیها صحیح نباشد. این APIها گزینههایی را برای لغو این پیشفرضها ارائه میدهند.
برای مشخص کردن اندازههای ذاتی 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. }
برای شما توصیه میشود
- توجه: متن لینک زمانی نمایش داده میشود که جاوا اسکریپت غیرفعال باشد.
- طرحبندیهای سفارشی {:#custom-layouts}
- خطوط ترازبندی در Jetpack Compose
- مراحل نوشتن Jetpack