בקטע 'כתיבה', אפשר לשרשר כמה מקשי צירוף יחד כדי לשנות את המראה תחושה של קומפוזביליות. שרשראות הצירוף האלה יכולות להשפיע על המגבלות שעברו לתכנים קומפוזביליים, שמגדירים גבולות רוחב וגובה.
בדף הזה נסביר איך מגבילי התאמה בשרשרת משפיעים על האילוצים, וכתוצאה מכך מדידה ומיקום של תכנים קומפוזביליים.
מגבילי התאמה בעץ ממשק המשתמש
כדי להבין איך מגבילי ההתאמה משפיעים זה על זה, כדאי להמחיש איך הם מופיעים בעץ ממשק המשתמש, שנוצר במהלך שלב היצירה. עבור תוכלו לקרוא מידע נוסף בקטע יצירה מוזיקלית.
בעץ ממשק המשתמש, אפשר לראות באופן חזותי את המגבילים כצומתי wrapper לפריסה צמתים:
![קוד לתכנים קומפוזביליים ומגבילים, והייצוג החזותי שלהם כעץ ממשק משתמש.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/modifier-wrapping.png?authuser=1&hl=he)
הוספה של יותר ממאפיין אחד של תוכן קומפוזבילי יוצרת שרשרת של מגבילים. מתי
ליצור שרשרת של מספר רכיבי שינוי, כל צומת של הצירוף עוטף את שאר השרשרת
וצומת הפריסה שבתוכו. לדוגמה, כשיוצרים שרשרת של clip
size
, הצומת של הצירוף clip
שמסביב לצומת הצירוף size
,
שאחר כך עוטף את הצומת של הפריסה Image
.
בשלב הפריסה, האלגוריתם שעובר על העץ נשאר ללא שינוי, הוא גם מקבל ביקור בכל צומת של צירוף. כך אפשר לשנות את הגודל הדרישות והמיקום של הצירוף או צומת הפריסה שהוא כולל.
כפי שמוצג באיור 2, ההטמעה של התכנים הקומפוזביליים Image
ו-Text
שהם מכילים שרשרת של רכיבי שינוי שעוטפים צומת פריסה יחיד.
של Row
ו-Column
הם פשוט צמתים בפריסה שמתארת איך
כדי להזמין את הילדים.
![מבנה העץ מהעבר, אבל עכשיו כל צומת הוא רק פריסה פשוטה, עם הרבה צמתים שעוטפים את הצומת.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/composables-modifiers.png?authuser=1&hl=he)
לסיכום:
- מגבילי התאמה גורפים צומת של מקש צירוף או פריסה יחיד.
- צמתים של פריסה יכולים לפרוס מספר צומתי צאצא.
בקטעים הבאים מתואר איך להשתמש במודל התודעתי הזה כדי שרשרת משנה ואיך היא משפיעה על הגודל של תכנים קומפוזביליים.
מגבלות בשלב הפריסה
שלב הפריסה מבוסס על אלגוריתם שמורכב משלושה שלבים כדי למצוא כל פריסה רוחב, גובה וקואורדינטה x ו-y של הצומת:
- מדידת צאצאים: צומת מודד את הצאצאים שלו, אם יש כאלה.
- בחירת גודל משלו: על סמך המדידות האלה, צומת מחליט בעצמו גודל.
- מיקום צאצאים: כל צומת צאצא ממוקם ביחס לצומת שלו המיקום.
בעזרת Constraints
אפשר למצוא את הגדלים המתאימים לצמתים במהלך שני הצמתים הראשונים
באלגוריתם. האילוצים מגדירים את גבולות המינימום והמקסימום
הרוחב והגובה של הצומת. כשהצומת קובע את הגודל שלו, הגודל שלו נמדד
צריכים להיות בטווח הגדלים הזה.
סוגי מגבלות
האילוץ יכול להיות אחת מהאפשרויות הבאות:
- מוגבל: לצומת יש רוחב וגובה מינימליים ומקסימליים.
![אילוצים מוגבלים בגדלים שונים בתוך קונטיינר.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/bounded-constraints.png?authuser=1&hl=he)
- ללא גבולות: הצומת לא מוגבל לגודל כלשהו. הרוחב המקסימלי וגם גבולות הגובה מוגדרים לאינסוף.
![אילוצים לא מוגבלים שבהם הרוחב והגובה מוגדרים לאינסוף. האילוצים חורגים מהמאגר.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/unbounded-constraints.png?authuser=1&hl=he)
- מדויקת: הצומת נדרש לעמוד בדרישת גודל מדויקת. המינימום והגבולות המקסימליים מוגדרים לאותו ערך.
![אילוצים מדויקים שתואמים לדרישת הגודל המדויק בתוך הקונטיינר.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/exact-constraints.png?authuser=1&hl=he)
- שילוב: הצומת מורכב משילוב של סוגי האילוצים שלמעלה. לדוגמה, אילוץ יכול להגביל את הרוחב ובמקביל לאפשר גובה מקסימלי בלתי מוגבל, או להגדיר רוחב מדויק אבל להגדיר גובה מוגבל.
![שני קונטיינרים שמציגים שילובים של אילוצים עם הגבלות ותחומים לא מוגבלים, ורוחב וגובה מדויקים.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/combination-constraints.png?authuser=1&hl=he)
הקטע הבא מתאר איך האילוצים האלה מועברים מהורה לילדים.
איך מגבלות מועברות מהורה לילד
במהלך השלב הראשון של האלגוריתם המתואר בקטע מגבלות בפריסה שלב, האילוצים מועברים מהורה לילד בעץ ממשק המשתמש.
כשצומת הורה מודד את הצאצאים שלו, הוא מספק את האילוצים האלה לכל כדי שהצופים ידעו כמה גדולים או קטנים הם יכולים להיות. לאחר מכן, כש מחליט את גודלו, הוא גם פועל בהתאם למגבלות שהעבירו ההורים שלו.
ככלל, האלגוריתם פועל באופן הבא:
- כדי לקבוע את הגודל בפועל שברצונך לתפוס, הצומת של הרמה הבסיסית (root) בעץ ממשק המשתמש ומודדת את הצאצאים שלו ומעבירה את אותן מגבלות אל הצאצא הראשון שלו.
- אם הילד או הילדה הם תכונת שינוי שלא משפיעה על המדידה, היא מעבירה את מגבלות להתאמה הבאה. המגבלות מועברות למטה רשת כפי שהיא, אלא אם מתקבל ערך לשינוי שמשפיע על המדידה. לאחר מכן, גודלם משתנה בהתאם.
- לאחר הגעה לצומת שאין לו צאצאים (נקרא 'עלה' צומת), הוא קובע את גודלו על סמך המגבלות שהועברו, ו הפונקציה מחזירה את הגודל הזה להורה שלו.
- ההורה משנה את המגבלות שלו בהתאם למדידות של הילד או הילדה, קוראת לצאצא הבא עם המגבלות המותאמות האלה.
- לאחר שכל הצאצאים של הורה נמדדים, הצומת ההורה מחליט על בגודל האישי שלו, ומעביר אותו להורה שלו.
- כך מתבצעת חצייה של העץ כולו לעומק. בסופו של דבר, כל הצמתים החליטה על גודלם, ושלב המדידה הושלם.
אפשר לראות דוגמה מפורטת יותר במאמר מגבלות וסדר מגביל. וידאו.
מגבילי התאמה שמשפיעים על מגבלות
למדנו בקטע הקודם שמגבילים מסוימים יכולים להשפיע על האילוץ גודל. בקטעים הבאים מתוארים שינויים ספציפיים שמשפיעים על מגבלות בפועל.
ערך לשינוי בשדה size
הצירוף size
מציין את הגודל המועדף של התוכן.
לדוגמה, יש לעבד את עץ ממשק המשתמש הבא בקונטיינר 300dp
מאת 200dp
. האילוצים הם במסגרת תחום, ומאפשרים רוחב בין 100dp
ל-
300dp
, ובגבהים בין 100dp
ל-200dp
:
![חלק מעץ ממשק משתמש עם תכונת השינוי של הגודל שעוטפת צומת פריסה,
ייצוג של המגבלות הגבולות שנקבעו על ידי מאפיין הגודל בקונטיינר.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/size-modifier.png?authuser=1&hl=he)
מגביל size
מתאים את המגבלות הנכנסות כך שיתאימו לערך שמועבר אליו.
בדוגמה הזו, הערך הוא 150dp
:
![זהה לאיור 7, למעט עם שינוי הגודל שמאפשר להתאים את המגבלות הנכנסות כך שיתאימו לערך שמועבר אליו.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/size-modifier-2.png?authuser=1&hl=he)
size
משנה את האילוצים ל-150dp
.אם הרוחב והגובה קטנים מגבול האילוץ הקטן ביותר, או גדול מגבול האילוץ הגדול ביותר, סכום הצירוף תואם את עד כמה שאפשר תוך ציות למגבלות שהוגדרו ב:
![שני עצים של ממשק המשתמש והייצוגים התואמים שלהם בקונטיינרים. בשלב הראשון,
מגביל גודל מקבל את מגבלות ההמרה; בשנייה, מגביל הגודל יתאים את עצמו
מגבלות גדולות מדי ככל האפשר, וכתוצאה מכך נוצרים אילוצים שממלאים את המכל.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/size-modifier-3.png?authuser=1&hl=he)
size
, בהתאם לאילוץ שהועבר באותה מידה
ככל האפשר.לתשומת ליבך, שרשור של כמה מתאמים של size
לא פועל. size
הראשונים
מקש הצירוף מגדיר את מגבלות המינימום והמקסימום כערך קבוע. גם אם
גם תכונת השינוי של הגודל השני מבקשת גודל קטן או גדול יותר, היא עדיין צריכה
לעמוד בגבולות המדויקים שנקבעו, כך שהיא לא תעקוף את הערכים האלה:
![שרשרת של שתי אפשרויות לשינוי גודל בעץ ממשק המשתמש והייצוג שלו בקונטיינר,
וזו התוצאה של הערך הראשון שהועבר ולא של הערך השני.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/size-modifier-4.png?authuser=1&hl=he)
size
, שבה הערך השני עבר
in (50dp
) לא מבטל את הערך הראשון (100dp
).ערך לשינוי בשדה requiredSize
אם צריךrequiredSize
size
כדי לעקוף את האילוצים הנכנסים. מקש הצירוף requiredSize
מחליף את
את המגבלות שהתקבלו ומעביר את הגודל שצוין כגבולות מדויקים.
כשהגודל מועבר חזרה בעץ, הצומת הצאצא יתרכז שטח פנוי:
![מגביל הגודל והגודל הנדרש משורשרים בעץ ממשק משתמש,
ייצוג בו-זמנית בקונטיינר. מגבלות החובה של מגביל הגודל מבטלות את התאמת הגודל
מגבלות בפועל.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/requiredsize-modifier.png?authuser=1&hl=he)
requiredSize
מבטל את האילוצים הנכנסים מ-
מקש הצירוף size
.מגבילי width
ו-height
תכונת הצירוף size
מתאימה את הרוחב וגם את הגובה של המגבלות. ב-
מקש הצירוף width
, אפשר להגדיר רוחב קבוע אבל להשאיר את הגובה לא קבוע.
באותו אופן, בעזרת הצירוף height
אפשר להגדיר גובה קבוע, אבל להשאיר את
רוחב לא קבוע:
![שני עצים של ממשק המשתמש, אחד עם מקש הצירוף של הרוחב והייצוג של הקונטיינר שלו
באמצעות מקש ההתאמה של הגובה והייצוג שלו.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/width-height-modifier.png?authuser=1&hl=he)
width
ומגביל הצירוף height
רוחב קבוע
ו-גובה, בהתאמה.ערך לשינוי בשדה sizeIn
מגביל sizeIn
מאפשר להגדיר מגבלות מינימום ומקסימום מדויקות
את הרוחב והגובה. אפשר להשתמש בתכונת השינוי sizeIn
אם נדרשת שליטה פרטנית
מעבר למגבלות.
![עץ ממשק משתמש עם תכונת הצירוף sizeIn עם ערכי רוחב וגובה מינימליים ומקסימליים,
והייצוג שלו בתוך קונטיינר.](https://developer.android.com/static/develop/ui/compose/images/layouts/constraints-modifiers/sizein-modifier.png?authuser=1&hl=he)
sizeIn
עם minWidth
, maxWidth
, minHeight
ועם
maxHeight
הוגדר.דוגמאות
בקטע הזה מוצג ומסביר את הפלט מכמה קטעי קוד עם משורשרים.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .size(50.dp) )
קטע הקוד הזה יפיק את הפלט הבא:
- מקש הצירוף
fillMaxSize
משנה את המגבלות כדי להגדיר גם רוחב וגובה מינימליים לערך המקסימלי —300dp
ברוחב ו-200dp
לגובה. - גם אם מגביל
size
רוצה להשתמש בגודל של50dp
, הוא עדיין צריך לפעול בהתאם למגבלות המינימליות שמתקבלות. לכן הצירוףsize
גם פלט את גבולות האילוץ המדויקים של300
עד200
, באופן אפקטיבי תוך התעלמות מהערך שצוין בתכונת הצירוףsize
. - השדה
Image
תואם לגבולות האלה ומדווח על גודל של300
עד200
, מועבר לאורך כל הדרך במעלה העץ.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .fillMaxSize() .wrapContentSize() .size(50.dp) )
קטע הקוד הזה יפיק את הפלט הבא:
- מגביל
fillMaxSize
מתאים את המגבלות כדי להגדיר גם רוחב וגובה לערך המקסימלי —300dp
ברוחב ו-200dp
אינץ' גובה. - מקש הצירוף
wrapContentSize
מאפס את המגבלות המינימליות. כך שלמרות במסגרתfillMaxSize
התבצעו מגבלות קבועות, אבלwrapContentSize
איפס/ה אותו בחזרה למגבלות מוגבלות. הצומת הבא יכול עכשיו לתפוס את כל השטח שוב, או להיות קטן יותר מכל המרחב. - מגביל
size
מגדיר את גבולות המינימום והמקסימום של50
. - הערך של
Image
מקבל את הגודל50
עד50
, וגם הערך של הצירוףsize
קדימה. - למגביל הצירוף
wrapContentSize
יש מאפיין מיוחד. הוא לוקח ושמה אותו במרכז של הגבולות המינימליים הזמינים. מועבר אליה. הגודל שהוא מעביר להורים שלו שווה גבולות מינימליים שהועברו אליו.
על ידי שילוב של שלושה מגבילים בלבד, אפשר להגדיר גודל של התוכן הקומפוזבילי למרכז אותו בהורה שלו.
Image( painterResource(R.drawable.hero), contentDescription = null, Modifier .clip(CircleShape) .padding(10.dp) .size(100.dp) )
קטע הקוד הזה יפיק את הפלט הבא:
- הצירוף
clip
לא משנה את המגבלות.- תכונת הצירוף
padding
מפחיתה את המגבלות המקסימליות. - מקש הצירוף
size
מגדיר את כל המגבלות כ-100dp
. - השדה
Image
פועל בהתאם למגבלות האלה ומדווח בגודל של100
עד100dp
. - הצירוף
padding
מוסיף10dp
בכל הגדלים, כך שהוא מגדיל את הרוחב והגובה של20dp
. - בשלב השרטוט, הצירוף
clip
פועל על קנבס של120
מאת120dp
. לכן, היא יוצרת מסכה של עיגול בגודל הזה. - לאחר מכן, המגביל
padding
מטמיע את התוכן שלו ב-10dp
לכל הגדלים, כך מקטין את גודל הקנבס ל-100
ב-100dp
. - השדה
Image
מצויר באזור העריכה הזה. התמונה נחתכה על סמך המעגל המקורי של120dp
, כך שהפלט הוא תוצאה לא עגולה.
- תכונת הצירוף