من قواعد Compose أنّه يجب قياس العناصر التابعة مرة واحدة فقط، لأنّ قياسها مرتين يؤدي إلى حدوث استثناء في وقت التشغيل. ومع ذلك، هناك أوقات تحتاج فيها إلى بعض المعلومات عن أطفالك قبل قياسهم.
تتيح لك مقاييس Intrinsics إرسال طلبات بحث عن الأطفال قبل قياس أدائهم فعليًا.
يمكنك طلب 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
مع رسم النص في سطر واحد.
استخدام الدالات الجوهرية
لنفترض أنّنا نريد إنشاء عنصر قابل للإنشاء يعرض نصَين على الشاشة مفصولَين بمقسّم على النحو التالي:
كيف يمكننا تحقيق ذلك؟ يمكننا الحصول على 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)
على العناصر الفرعية أن يكون ارتفاعها مساويًا للحد الأدنى للارتفاع الداخلي. بما أنّها متكرّرة، ستطلب 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") } } }
مع معاينة:
ستكون قيمة minIntrinsicHeight
للعنصر القابل للإنشاء Row
هي الحد الأقصى
minIntrinsicHeight
للعناصر التابعة له. قيمة 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. }
أفلام مُقترَحة لك
- ملاحظة: يتم عرض نص الرابط عندما تكون JavaScript غير مفعّلة
- التنسيقات المخصّصة {:#custom-layouts }
- خطوط المحاذاة في Jetpack Compose
- مراحل Jetpack Compose