סדר המעבר הוא הסדר שבו שירותי הנגישות מנווטים בין רכיבי ממשק המשתמש. באפליקציית כתיבה, האלמנטים מסודרים לפי סדר הקריאה הצפוי, בדרך כלל משמאל לימין ואז מלמעלה למטה. עם זאת, יש כמה תרחישים שבהם יכול להיות שמערכת ה-Compose תצטרך רמזים נוספים כדי לקבוע את סדר הקריאה הנכון.
isTraversalGroup
ו-traversalIndex
הם מאפיינים סמנטיים שמאפשרים לכם להשפיע על סדר הסריקה של שירותי הנגישות בתרחישים שבהם אלגוריתם המיון שמוגדר כברירת מחדל ב-Compose לא מספיק. isTraversalGroup
מאפשר לזהות קבוצות חשובות מבחינה סמנטית שצריך לבצע בהן התאמה אישית, ו-traversalIndex
מאפשר לשנות את הסדר של רכיבים ספציפיים בתוך הקבוצות האלה.
אפשר להשתמש ב-isTraversalGroup
בלבד כדי לציין שצריך לבחור את כל הרכיבים בקבוצה יחד, או להשתמש ב-traversalIndex
כדי לבצע התאמה אישית נוספת.
משתמשים ב-isTraversalGroup
וב-traversalIndex
באפליקציה כדי לקבוע את סדר הסריקה של קורא המסך.
קיבוץ רכיבים לצורך סריקה
isTraversalGroup
הוא מאפיין בוליאני שמגדיר אם צומת סמנטיקה הוא קבוצת סריקה. סוג הצומת הזה משמש כגבול לארגון הצאצאים של הצומת.
הגדרת isTraversalGroup = true
בצומת מסוים פירושה שכל הצאצאים של הצומת הזה ייבדקו לפני המעבר לרכיבים אחרים. אפשר להגדיר את isTraversalGroup
בצמתים שלא ניתן להתמקד בהם באמצעות קורא מסך, כמו עמודות, שורות או תיבות.
בדוגמה הבאה נעשה שימוש ב-isTraversalGroup
. הוא פולט ארבעה רכיבי טקסט. שני הרכיבים שבצד ימין שייכים לרכיב CardBox
אחד, ושני הרכיבים שבצד ימין שייכים לרכיב CardBox
אחר:
// CardBox() function takes in top and bottom sample text. @Composable fun CardBox( topSampleText: String, bottomSampleText: String, modifier: Modifier = Modifier ) { Box(modifier) { Column { Text(topSampleText) Text(bottomSampleText) } } } @Composable fun TraversalGroupDemo() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is " val bottomSampleText2 = "on the right." Row { CardBox( topSampleText1, bottomSampleText1 ) CardBox( topSampleText2, bottomSampleText2 ) } }
הקוד יוצר פלט דומה לזה:

מכיוון שלא הוגדרה סמנטיקה, ברירת המחדל של קורא המסך היא לעבור על הרכיבים מימין לשמאל ומלמעלה למטה. בגלל ההגדרה שמוגדרת כברירת מחדל, TalkBack קורא את קטעי המשפט בסדר הלא נכון:
"המשפט הזה נמצא" → "המשפט הזה הוא" → "בעמודה הימנית". → "בצד שמאל".
כדי לסדר את הקטעים בצורה נכונה, משנים את קטע הקוד המקורי כך שisTraversalGroup
יהיה true
:
@Composable fun TraversalGroupDemo2() { val topSampleText1 = "This sentence is in " val bottomSampleText1 = "the left column." val topSampleText2 = "This sentence is" val bottomSampleText2 = "on the right." Row { CardBox( // 1, topSampleText1, bottomSampleText1, Modifier.semantics { isTraversalGroup = true } ) CardBox( // 2, topSampleText2, bottomSampleText2, Modifier.semantics { isTraversalGroup = true } ) } }
מכיוון ש-isTraversalGroup
מוגדר באופן ספציפי לכל CardBox
, הגבולות של CardBox
חלים על מיון הרכיבים שלו. במקרה כזה, ה-CardBox
הימני נקרא קודם, ואחריו ה-CardBox
הימני.
עכשיו, TalkBack יקריא את קטעי המשפט בסדר הנכון:
"המשפט הזה נמצא" → "בעמודה הימנית". → "המשפט הזה הוא" → "בצד שמאל".
התאמה אישית של סדר הטרaversal
traversalIndex
הוא מאפיין מסוג float שמאפשר להתאים אישית את סדר הסריקה של TalkBack. אם קיבוץ רכיבים לא מספיק כדי ש-TalkBack יפעל בצורה תקינה, תוכלו להשתמש ב-traversalIndex
בשילוב עם isTraversalGroup
כדי להתאים אישית את הסדר של קורא המסך.
למאפיין traversalIndex
יש את המאפיינים הבאים:
- רכיבים עם ערכים נמוכים יותר של
traversalIndex
מקבלים עדיפות ראשונה. - יכול להיות חיובי או שלילי.
- ערך ברירת המחדל הוא
0f
. - כדי שמדד הניווט ישפיע על התנהגות הניווט, צריך להגדיר אותו ברכיב ששירותי הנגישות יוכלו לבחור בו ולהתמקד בו, כמו רכיבים במסך כמו טקסט או לחצנים.
- הגדרת
traversalIndex
בלבד, לדוגמה, ב-Column
לא תשפיע, אלא אם גם העמודה מוגדרת כ-isTraversalGroup
.
- הגדרת
בדוגמה הבאה מוסבר איך משתמשים ב-traversalIndex
וב-isTraversalGroup
יחד.
תצוגת שעון היא תרחיש נפוץ שבו סדר traversal סטנדרטי לא עובד. הדוגמה בקטע הזה היא בורר זמן, שבו המשתמש יכול לעבור בין המספרים בתצוגת השעון ולבחור ספרות בשדות השעה והדקה.

בקטע הקוד הפשוט הבא מופיע CircularLayout
שבו מצוירים 12 מספרים, מתחילים ב-12 וממשיכים בכיוון השעון סביב העיגול:
@Composable fun ClockFaceDemo() { CircularLayout { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier) { Text((if (value == 0) 12 else value).toString()) } }
מכיוון שתצוגת השעון לא נקראת באופן לוגי לפי סדר ברירת המחדל משמאל לימין ומלמעלה למטה, המספרים נקראים על ידי TalkBack בסדר לא תקין. כדי לתקן את הבעיה, צריך להשתמש בערך המונה המצטבר, כפי שמתואר בקטע הקוד הבא:
@Composable fun ClockFaceDemo() { CircularLayout(Modifier.semantics { isTraversalGroup = true }) { repeat(12) { hour -> ClockText(hour) } } } @Composable private fun ClockText(value: Int) { Box(modifier = Modifier.semantics { this.traversalIndex = value.toFloat() }) { Text((if (value == 0) 12 else value).toString()) } }
כדי להגדיר את סדר הטרaversal בצורה נכונה, קודם צריך להפוך את CircularLayout
לקבוצת טרaversal ולהגדיר את isTraversalGroup = true
. לאחר מכן, כשכל טקסט של השעון מצויר בפריסה, מגדירים את הערך התואם של traversalIndex
לערך המונה.
מכיוון שערך המונה עולה כל הזמן, הערך של traversalIndex
בכל ערך של השעון גדול יותר ככל שמוסיפים מספרים למסך. לערך השעון 0 הערך של traversalIndex
הוא 0, ולערך השעון 1 הערך של traversalIndex
הוא 1.
כך מוגדר הסדר שבו TalkBack יקריא אותם. עכשיו, המספרים בתוך CircularLayout
יקראו בסדר הצפוי.
מכיוון שהערכים של traversalIndexes
שהוגדרו הם יחסיים רק למפתחות אחרים באותו קיבוץ, שאר הסדר במסך נשמר. במילים אחרות, השינויים הסמנטיים שמוצגים בקטע הקוד הקודם משנים רק את הסדר בתוך לוח השעון שבו מוגדר isTraversalGroup = true
.
חשוב לזכור: גם אם לא תגדירו את הסמנטיקה של CircularLayout's
כ-isTraversalGroup =
true
, השינויים ב-traversalIndex
עדיין יחולו. עם זאת, בלי הקישור CircularLayout
, 12 הספרות של לוח השעון יקראו בסוף, אחרי שכל שאר הפריטים במסך ייקראו. הסיבה לכך היא שלכל שאר הרכיבים יש ערך traversalIndex
שמוגדר כברירת מחדל כ-0f
, ורכיבי הטקסט של השעון נקרא אחרי כל שאר רכיבי 0f
.
שיקולים לשימוש ב-API
כשמשתמשים ב-API לטרaversal, כדאי לשים לב לדברים הבאים:
- צריך להגדיר את
isTraversalGroup = true
ברכיב ההורה שמכיל את הרכיבים המקובצים. - צריך להגדיר את
traversalIndex
ברכיב צאצא שמכיל סמנטיקה, והוא ייבחר על ידי שירותי הנגישות. - חשוב לוודא שכל הרכיבים שאתם בודקים נמצאים באותה רמה של
zIndex
, כי זה משפיע גם על הסמנטיקה ועל סדר הטרaversal. - חשוב לוודא שלא מתבצע מיזוג מיותר של סמנטיקה, כי זה עלול להשפיע על הרכיבים שעליהם מוגדרים אינדקסי הניווט.
מומלץ עבורך
- הערה: טקסט הקישור מוצג כש-JavaScript מושבת
- נגישות ב-Compose
- [Material Design 2 ב-Compose][19]
- בדיקת הפריסה של 'כתיבה'