تتمثل إحدى قواعد Compose في أنه يجب قياس أطفالك مرة واحدة فقط، ويؤدي قياس الأطفال مرتين إلى حدوث استثناء في وقت التشغيل. ومع ذلك، هناك أوقات تحتاج فيها إلى بعض المعلومات حول أطفالك قبل قياسها.
تسمح لك السمات الأساسية باستعلام الأطفال قبل قياسهم فعليًا.
يمكنك طلب intrinsicWidth
أو intrinsicHeight
للعنصر القابل للتجميع:
(min|max)IntrinsicWidth
: استنادًا إلى هذا العرض، ما هو الحد الأدنى/الحد الأقصى للعرض الذي يمكنك من خلاله رسم المحتوى بشكل صحيح؟(min|max)IntrinsicHeight
: استنادًا إلى هذا الارتفاع، ما هو الحد الأدنى/الحد الأقصى للارتفاع الذي يمكنك من خلاله رسم المحتوى بشكل صحيح؟
على سبيل المثال، إذا طلبت minIntrinsicHeight
من Text
مع
height
لانهائي، سيعرض ال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 ) 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
هو الحد الأقصى
minIntrinsicHeight
لعناصره الثانوية. قيمة minIntrinsicHeight
للعنصر Divider
تكون 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