מגבלות וסדר מגביל

בקטע 'כתיבה', אפשר לשרשר כמה מקשי צירוף יחד כדי לשנות את המראה תחושה של קומפוזביליות. שרשראות הצירוף האלה יכולות להשפיע על המגבלות שעברו לתכנים קומפוזביליים, שמגדירים גבולות רוחב וגובה.

בדף הזה נסביר איך מגבילי התאמה בשרשרת משפיעים על האילוצים, וכתוצאה מכך מדידה ומיקום של תכנים קומפוזביליים.

מגבילי התאמה בעץ ממשק המשתמש

כדי להבין איך מגבילי ההתאמה משפיעים זה על זה, כדאי להמחיש איך הם מופיעים בעץ ממשק המשתמש, שנוצר במהלך שלב היצירה. עבור תוכלו לקרוא מידע נוסף בקטע יצירה מוזיקלית.

בעץ ממשק המשתמש, אפשר לראות באופן חזותי את המגבילים כצומתי wrapper לפריסה צמתים:

קוד לתכנים קומפוזביליים ומגבילים, והייצוג החזותי שלהם כעץ ממשק משתמש.
איור 1. מגבילי התאמה שעוטפים צמתים של פריסה בעץ ממשק המשתמש.

הוספה של יותר ממאפיין אחד של תוכן קומפוזבילי יוצרת שרשרת של מגבילים. מתי ליצור שרשרת של מספר רכיבי שינוי, כל צומת של הצירוף עוטף את שאר השרשרת וצומת הפריסה שבתוכו. לדוגמה, כשיוצרים שרשרת של clip size, הצומת של הצירוף clip שמסביב לצומת הצירוף size, שאחר כך עוטף את הצומת של הפריסה Image.

בשלב הפריסה, האלגוריתם שעובר על העץ נשאר ללא שינוי, הוא גם מקבל ביקור בכל צומת של צירוף. כך אפשר לשנות את הגודל הדרישות והמיקום של הצירוף או צומת הפריסה שהוא כולל.

כפי שמוצג באיור 2, ההטמעה של התכנים הקומפוזביליים Image ו-Text שהם מכילים שרשרת של רכיבי שינוי שעוטפים צומת פריסה יחיד. של Row ו-Column הם פשוט צמתים בפריסה שמתארת איך כדי להזמין את הילדים.

מבנה העץ מהעבר, אבל עכשיו כל צומת הוא רק פריסה פשוטה, עם הרבה צמתים שעוטפים את הצומת.
איור 2. אותו מבנה עץ כמו באיור 1, אך עם תכנים קומפוזביליים עץ ממשק המשתמש שמוצג כשרשראות של מגבילי התאמה.

לסיכום:

  • מגבילי התאמה גורפים צומת של מקש צירוף או פריסה יחיד.
  • צמתים של פריסה יכולים לפרוס מספר צומתי צאצא.

בקטעים הבאים מתואר איך להשתמש במודל התודעתי הזה כדי שרשרת משנה ואיך היא משפיעה על הגודל של תכנים קומפוזביליים.

מגבלות בשלב הפריסה

שלב הפריסה מבוסס על אלגוריתם שמורכב משלושה שלבים כדי למצוא כל פריסה רוחב, גובה וקואורדינטה x ו-y של הצומת:

  1. מדידת צאצאים: צומת מודד את הצאצאים שלו, אם יש כאלה.
  2. בחירת גודל משלו: על סמך המדידות האלה, צומת מחליט בעצמו גודל.
  3. מיקום צאצאים: כל צומת צאצא ממוקם ביחס לצומת שלו המיקום.

בעזרת Constraints אפשר למצוא את הגדלים המתאימים לצמתים במהלך שני הצמתים הראשונים באלגוריתם. האילוצים מגדירים את גבולות המינימום והמקסימום הרוחב והגובה של הצומת. כשהצומת קובע את הגודל שלו, הגודל שלו נמדד צריך להיות בטווח הגדלים הזה.

סוגי מגבלות

האילוץ יכול להיות אחת מהאפשרויות הבאות:

  • מוגבל: לצומת יש רוחב וגובה מינימליים ומקסימליים.
אילוצים מוגבלים בגדלים שונים בתוך קונטיינר.
איור 3. אילוצים מוגבלים.
  • ללא גבולות: הצומת לא מוגבל לגודל כלשהו. הרוחב המקסימלי וגם גבולות הגובה מוגדרים לאינסוף.
אילוצים לא מוגבלים שבהם הרוחב והגובה מוגדרים לאינסוף. האילוצים חורגים מהמאגר.
איור 4. מגבלות בלתי מוגבלות.
  • מדויקת: הצומת נדרש לעמוד בדרישת גודל מדויקת. המינימום והגבולות המקסימליים מוגדרים לאותו ערך.
אילוצים מדויקים שתואמים לדרישת הגודל המדויק בתוך הקונטיינר.
איור 5. מגבלות מדויקות.
  • שילוב: הצומת מורכב משילוב של סוגי האילוצים שלמעלה. לדוגמה, אילוץ יכול להגביל את הרוחב ובמקביל לאפשר גובה מקסימלי בלתי מוגבל, או להגדיר רוחב מדויק אבל להגדיר גובה מוגבל.
שני קונטיינרים שמציגים שילובים של אילוצים עם הגבלות ותחומים לא מוגבלים, ורוחב וגובה מדויקים.
איור 6. שילובים של מגבלות עם הגבלות, הגבלות עם הגבלות ורוחב מדויק וגבהים.

הקטע הבא מתאר איך האילוצים האלה מועברים מהורה לילדים.

איך מגבלות מועברות מהורה לילד

במהלך השלב הראשון של האלגוריתם המתואר בקטע מגבלות בפריסה שלב, האילוצים מועברים מהורה לילד בעץ ממשק המשתמש.

כשצומת הורה מודד את הצאצאים שלו, הוא מספק את האילוצים האלה לכל כדי שהצופים ידעו כמה גדולים או קטנים הם יכולים להיות. לאחר מכן, כש מחליט את גודלו, הוא גם פועל בהתאם למגבלות שהעבירו ההורים שלו.

ככלל, האלגוריתם פועל באופן הבא:

  1. כדי לקבוע את הגודל בפועל שברצונך לתפוס, הצומת של הרמה הבסיסית (root) בעץ ממשק המשתמש ומודדת את הצאצאים שלו ומעבירה את אותן מגבלות אל הצאצא הראשון שלו.
  2. אם הילד או הילדה הם תכונת שינוי שלא משפיעה על המדידה, היא מעבירה את מגבלות להתאמה הבאה. המגבלות מועברות למטה רשת כפי שהיא, אלא אם מתקבל ערך לשינוי שמשפיע על המדידה. לאחר מכן, גודלם משתנה בהתאם.
  3. לאחר הגעה לצומת שאין לו צאצאים (נקרא 'עלה' צומת), הוא קובע את גודלו על סמך המגבלות שהועברו, ו הפונקציה מחזירה את הגודל הזה להורה שלו.
  4. ההורה משנה את המגבלות שלו בהתאם למדידות של הילד או הילדה, קוראת לצאצא הבא עם המגבלות המותאמות האלה.
  5. לאחר שכל הצאצאים של הורה נמדדים, הצומת ההורה מחליט על בגודל האישי שלו, ומעביר אותו להורה שלו.
  6. כך מתבצעת חצייה של העץ כולו לעומק. בסופו של דבר, כל הצמתים החליטה על גודלם, ושלב המדידה הושלם.

אפשר לראות דוגמה מפורטת יותר במאמר מגבלות וסדר מגביל. וידאו.

מגבילי התאמה שמשפיעים על מגבלות

למדנו בקטע הקודם שמגבילים מסוימים יכולים להשפיע על האילוץ גודל. בקטעים הבאים מתוארים שינויים ספציפיים שמשפיעים על מגבלות בפועל.

ערך לשינוי בשדה size

הצירוף size מציין את הגודל המועדף של התוכן.

לדוגמה, יש לעבד את עץ ממשק המשתמש הבא בקונטיינר 300dp מאת 200dp. האילוצים מוגבלים והרוחב מאפשר בין 100dp ל- 300dp, ובגבהים בין 100dp ל-200dp:

חלק מעץ ממשק משתמש עם תכונת השינוי של הגודל שעוטפת צומת פריסה,
  ייצוג של המגבלות הגבולות שנקבעו על ידי מאפיין הגודל בקונטיינר.
איור 7. מגבלות מוגבלות בעץ ממשק המשתמש והייצוג שלו מאגר תגים.

מגביל size מתאים את המגבלות הנכנסות כך שיתאימו לערך שמועבר אליו. בדוגמה הזו, הערך הוא 150dp:

כמו באיור 7, מלבד עם שינוי הגודל, שמאפשר להתאים את המגבלות הנכנסות כך שיתאימו לערך שמועבר אליו.
איור 8. מקש הצירוף size משנה את האילוצים ל-150dp.

אם הרוחב והגובה קטנים מגבול האילוץ הקטן ביותר, או גדול מגבול האילוץ הגדול ביותר, סכום הצירוף תואם את עד כמה שאפשר תוך ציות למגבלות שהוגדרו ב:

שני עצים של ממשק המשתמש והייצוגים התואמים שלהם בקונטיינרים. בשלב הראשון,
  מגביל גודל מקבל את מגבלות ההמרה; בשנייה, מגביל הגודל יתאים את עצמו
  מגבלות גדולות מדי ככל האפשר, וכתוצאה מכך אילוצים ימלאו את המכל.
איור 9. מגביל size בהתאם לאילוץ שהועבר באותה מידה ככל האפשר.

לתשומת ליבך, שרשור של כמה מתאמים של size לא פועל. size הראשונים מקש הצירוף מגדיר את מגבלות המינימום והמקסימום כערך קבוע. גם אם גם תכונת השינוי של הגודל השני מבקשת גודל קטן או גדול יותר, היא עדיין צריכה לעמוד בגבולות המדויקים שנקבעו, כך שהיא לא תעקוף את הערכים האלה:

שרשרת של שתי אפשרויות לשינוי גודל בעץ ממשק המשתמש והייצוג שלו בקונטיינר,
  וזו התוצאה של הערך הראשון שהועבר ולא של הערך השני.
איור 10. שרשרת של שני מגבילי size, שבה הערך השני עבר in (50dp) לא מבטל את הערך הראשון (100dp).

ערך לשינוי בשדה requiredSize

אם צריךrequiredSizesize כדי לעקוף את האילוצים הנכנסים. מקש הצירוף requiredSize מחליף את את המגבלות שהתקבלו ומעביר את הגודל שצוין כגבולות מדויקים.

כשהגודל מועבר חזרה בעץ, הצומת הצאצא יתרכז שטח פנוי:

מגביל הגודל והגודל הנדרש משורשרים בעץ ממשק משתמש,
  ייצוג בו-זמנית בקונטיינר. מגבלות החובה של מגביל הגודל מבטלות את התאמת הגודל
  מגבלות בפועל.
איור 11. מקש הצירוף requiredSize מבטל את האילוצים הנכנסים מ- מקש הצירוף size.

מגבילי width ו-height

תכונת הצירוף size מתאימה את הרוחב וגם את הגובה של המגבלות. ב- מקש הצירוף width, אפשר להגדיר רוחב קבוע אבל להשאיר את הגובה לא קבוע. באותו אופן, בעזרת הצירוף height אפשר להגדיר גובה קבוע, אבל להשאיר את רוחב לא קבוע:

שני עצים של ממשק המשתמש, אחד עם מקש הצירוף של הרוחב והייצוג של הקונטיינר שלו
  באמצעות מקש ההתאמה של הגובה והייצוג שלו.
איור 12. הגדרת הצירוף של width ומגביל הצירוף height רוחב קבוע ו-גובה, בהתאמה.

ערך לשינוי בשדה sizeIn

מגביל sizeIn מאפשר להגדיר מגבלות מינימום ומקסימום מדויקות את הרוחב והגובה. אפשר להשתמש בתכונת השינוי sizeIn אם נדרשת שליטה פרטנית מעבר למגבלות.

עץ ממשק משתמש עם תכונת הצירוף sizeIn עם ערכי רוחב וגובה מינימליים ומקסימליים,
  והייצוג שלו בתוך קונטיינר.
איור 13. הצירוף 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, כך שהפלט הוא תוצאה לא עגולה.