קיבוץ יעדי המיקוד

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

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

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

  • ‫Enter: האירוע שמתרחש כשמעבירים את המיקוד מאלמנט כלשהו מחוץ לקבוצת המיקוד לאלמנט בתוך הקבוצה.
  • יציאה: האירוע שמתרחש כשהמיקוד עוזב את הרכיב הפנימי האחרון של הקבוצה ועובר ליעד מיקוד חיצוני.
דיאגרמה שמציגה מעברים של כניסה ויציאה בגבול של קבוצת מיקוד.
תרשים 1. קבוצת מיקוד עם אירועי כניסה ויציאה.

התנהגות ברירת המחדל של מעבר בין רכיבים

כברירת מחדל, כשקבוצת מיקוד מקבלת מיקוד מבחוץ:

  1. כניסה לקבוצה: Compose בוחר באופן אוטומטי יעד פנימי למיקוד. בניווט חד-ממדי (Tab), הוא בוחר את הרכיב הראשון בסדר ההצגה החזותי. בניווט דו-ממדי (מקשי החיצים או לחצני החיצים), נבחר הצאצא שהכי קרוב מבחינה גיאומטרית לכיוון הנכנס.
  2. ניווט בתוך הקבוצה: לחיצות חוזרות על מקש הניווט מעבירות את המיקוד בין יעדי המיקוד האחים שמוקפים בקבוצה.
  3. יציאה מהקבוצה: אחרי שהמשתמש מנווט אל מעבר ליעד המיקוד האחרון בתוך הקבוצה, הלחיצה הבאה על המקש מוציאה אותו מהקבוצה ומעבירה את המיקוד ליעד המיקוד הסמוך מחוץ לקבוצה.

התאמה אישית של ההפניה האוטומטית לכניסה למצב פוקוס

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

כוונה ותרחישי שימוש

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

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

תרחישים נפוצים אחרים לדוגמה:

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

הטמעה באמצעות onEnter ו-FocusRequester

כדי להפנות את המיקוד כשנכנסים לקבוצת מיקוד:

  1. מחילים את משנה המאפיין focusGroup על מאגר האב שמקיף את יעדי המיקוד הקשורים.
  2. מחילים את משנה הערך focusProperties על מאגר התגים, ומגדירים את הקריאה החוזרת (callback) onEnter.
  3. ב-onEnter callback (במסגרת FocusEnterExitScope), מתקשרים אל requestFocus() ב-FocusRequester שמשויך לצאצא ברירת המחדל המועדף באמצעות focusRequester.

val defaultChildRequester = remember { FocusRequester() }

Row(
    modifier = Modifier
        .focusGroup()
        .focusProperties {
            // Intercept entry into this group and redirect focus to the primary action
            onEnter = {
                defaultChildRequester.requestFocus()
            }
        }
) {
    Button(onClick = { /* Cancel action */ }) {
        Text("Cancel")
    }
    Button(
        onClick = { /* Confirm action */ },
        modifier = Modifier.focusRequester(defaultChildRequester)
    ) {
        Text("Confirm (Default)")
    }
}

בתוך onEnter ו-onExit, אפשר גם לקרוא ל-cancelFocusChange() כדי לחסום לחלוטין את מעברי המיקוד מעבר לגבול, או לבדוק את requestedFocusDirection כדי להתאים אישית את הניתוב בהתאם לאופן שבו המשתמש ניווט באמצעות Tab,‏ Down או Left.

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

ב-Jetpack Compose, מאגדים שניתן לגלול בהם כמו LazyRow,‏ LazyColumn ו-LazyVerticalGrid פועלים באופן אוטומטי כקבוצות מיקוד. לא צריך להחיל עליהם באופן מפורש את המגביל focusGroup כדי להגדיר קריאות חוזרות (callback) מסוג onEnter או onExit.