من قواعد 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