אחד מהכללים בניסוח האוטומטי הוא שצריך למדוד את ביצועי הילדים רק פעם אחת. כשמודדים ילדים, זו יכולה להיות חריגת זמן ריצה. אבל יש מקרים שבהם כשצריך מידע על הילדים לפני שהם מודדים אותם.
באמצעות Intrinsics אפשר להריץ שאילתות על ילדים לפני שהם נמדדים בפועל.
כדי ליצור תוכן קומפוזבילי, אפשר לבקש את ה-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 ) Divider( 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 ) 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
של התוכן הקומפוזבילי Row
יהיה הערך המקסימלי
minIntrinsicHeight
מהצאצאים שלה. של הרכיב Divider
הערך של minIntrinsicHeight
הוא 0 כי הוא לא תופס מקום אם אין מגבלות
נתון; הערך Text
יהיה minIntrinsicHeight
של הטקסט שצוין בשדה
width
לכן, האילוץ height
של הרכיב Row
יהיה
minIntrinsicHeight
מתוך Text
. לאחר מכן 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. }
מומלץ עבורך
- הערה: טקסט הקישור מוצג כאשר JavaScript מושבת
- פריסות בהתאמה אישית {:#custom-layouts }
- קווי יישור ב-Jetpack פיתוח נייטיב
- שלבי הכתיבה ב-Jetpack