یکی از قوانین Compose این است که فرزندان خود را فقط یک بار اندازه بگیرید. دو بار اندازهگیری کودکان استثناء زمان اجرا را ایجاد میکند. با این حال، مواقعی وجود دارد که قبل از اندازه گیری فرزندان خود به اطلاعاتی در مورد آنها نیاز دارید.
Intrinsics به شما این امکان را میدهد تا قبل از اینکه بچهها واقعاً اندازهگیری شوند، سؤال کنید.
برای یک کامپوزیشن، می توانید intrinsicWidth
یا intrinsicHeight
درونی آن را بخواهید:
-
(min|max)IntrinsicWidth
: با توجه به این عرض، حداقل/حداکثر عرضی که می توانید محتوای خود را به درستی نقاشی کنید چقدر است؟ -
(min|max)IntrinsicHeight
: با توجه به این ارتفاع، حداقل/حداکثر ارتفاعی که می توانید محتوای خود را به درستی نقاشی کنید چقدر است؟
به عنوان مثال، اگر از minIntrinsicHeight
یک Text
با height
بی نهایت بپرسید، 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 ) HorizontalDivider( 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 ) HorizontalDivider( 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") } } }
با پیش نمایش:
minIntrinsicHeight
Row
composable، حداکثر minIntrinsicHeight
فرزندان آن خواهد بود. minIntrinsicHeight
عنصر Divider
0 است زیرا در صورت عدم وجود محدودیت، فضا را اشغال نمی کند. Text
minIntrinsicHeight
همان متنی خواهد بود که width
خاصی دارد. بنابراین، محدودیت height
عنصر Row
حداکثر minIntrinsicHeight
Text
s خواهد بود. سپس Divider
height
خود را به محدودیت height
داده شده توسط Row
گسترش می دهد.
ذاتی در طرحبندیهای سفارشی شما
هنگام ایجاد یک Layout
سفارشی یا اصلاح کننده layout
، اندازه گیری های ذاتی به طور خودکار بر اساس تقریب ها محاسبه می شوند. بنابراین، محاسبات ممکن است برای همه طرحبندیها درست نباشد. این APIها گزینه هایی را برای لغو این پیش فرض ها ارائه می دهند.
برای تعیین اندازهگیریهای داخلی 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
- مراحل نوشتن جت پک