من بين قواعد الإنشاء أنه يجب عدم قياس محتوى أطفالك إلا مرة واحدة، علمًا بأنّ قياس الأداء مرتين يؤدي إلى استثناء باستثناء وقت التشغيل. ومع ذلك، تحتاج أحيانًا إلى بعض المعلومات عن أطفالك قبل قياسها.
يتيح لك تطبيق Intrinsic إرسال طلبات بحث إلى الأطفال قبل أن يتم قياسهم فعليًا.
إلى مركّب، يمكنك طلب توفّر intrinsicWidth
أو intrinsicHeight
:
(min|max)IntrinsicWidth
: نظرًا إلى هذا الارتفاع، ما هو الحد الأدنى/الحد الأقصى للعرض الذي يمكنك رسمه على المحتوى بشكل صحيح؟(min|max)IntrinsicHeight
: ما هو الحد الأدنى/الأقصى للارتفاع الذي يمكنك طلاء المحتوى به بشكل صحيح؟
على سبيل المثال، إذا طلبت minIntrinsicHeight
من Text
باستخدام لا نهائي
width
، سيتم عرض height
من Text
كما لو كان النص مرسومًا في
سطر واحد.
العملية العملية
لنفترض أنّنا نريد إنشاء قابل للإنشاء يعرض نصَين على الشاشة مفصولة بفاصلة مثل هذا:
كيف يمكننا تنفيذ ذلك؟ يمكن أن نمتلئ Row
بـ Text
، ثم يوسع النطاق
بأكبر قدر ممكن، ونضيف 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 ) Divider( color = Color.Black, modifier = Modifier.fillMaxHeight().width(1.dp) ) Text( modifier = Modifier .weight(1f) .padding(end = 4.dp) .wrapContentWidth(Alignment.End), text = text2 ) } }
إذا معاينةنا هذا، نرى أن الفاصل يتوسّع إلى الشاشة بأكملها، وهذا ليس ما نريده:
ويعود السبب في ذلك إلى أنّ 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 ) Divider( 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
القابل للإنشاء minIntrinsicHeight
هو الحد الأقصى
من أطفاله الثانويين.Row
وتكون قيمة العنصر Divider
للعنصر minIntrinsicHeight
هي 0 لأنّه لا يستهلك مساحة إذا لم يتم منح أي قيود، وستكون قيمة Text
minIntrinsicHeight
هي الخاصة بالنص المحدّد width
. وبالتالي، سيكون القيد height
للعنصر Row
هو الحد الأقصى
minIntrinsicHeight
من Text
. سيوسّع Divider
بعد ذلك height
إلى القيد 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. }