פיתוח למסכים בגדלים שונים


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

במדריך העיצוב מפורטים עקרונות העיצוב של פריסות דינמיות.

יצירת פריסות רספונסיביות באמצעות Material 3

השוליים של הפריסות צריכים להיות מבוססים על אחוזים. ב-Wear Compose Material 3, ScreenScaffold מחשב באופן אוטומטי את המרווח הפנימי לפי אחוזים ומספק contentPadding לביטוי הלמבדה של התוכן. צריך להעביר את הפרמטר contentPadding הזה אל TransformingLazyColumn.

בקטע הקוד הבא נעשה שימוש ברכיב TransformingLazyColumn כדי ליצור תוכן שנראה נהדר במגוון גדלים של מסכי Wear OS:

val columnState = rememberTransformingLazyColumnState()
val transformationSpec = rememberTransformationSpec()
ScreenScaffold(
    scrollState = columnState
) { contentPadding ->
    TransformingLazyColumn(
        state = columnState,
        contentPadding = contentPadding
    ) {
        item {
            ListHeader(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ListHeaderDefaults.minimumTopListContentPadding),
                transformation = SurfaceTransformation(transformationSpec)
            ) {
                Text(text = "Header")
            }
        }
        // ... other items
        item {
            Button(
                modifier = Modifier
                    .fillMaxWidth()
                    .transformedHeight(this, transformationSpec)
                    .minimumVerticalContentPadding(ButtonDefaults.minimumVerticalListContentPadding),
                transformation = SurfaceTransformation(transformationSpec),
                onClick = { /* ... */ },
                icon = {
                    Icon(
                        imageVector = Icons.Default.Build,
                        contentDescription = "build",
                    )
                },
            ) {
                Text(
                    text = "Build",
                    maxLines = 1,
                    overflow = TextOverflow.Ellipsis,
                )
            }
        }
    }
}

הדוגמה הזו ממחישה גם את ScreenScaffold ו-AppScaffold. הם מתאמים בין האפליקציה לבין מסכים ספציפיים (נתיבי ניווט) כדי להבטיח התנהגות גלילה נכונה ומיקום נכון של TimeText.

לגבי המרווח הפנימי העליון והתחתון, חשוב לשים לב גם לנקודות הבאות:

  • שימוש ב-Modifier.minimumVerticalContentPadding (כמו ListHeaderDefaults.minimumTopListContentPadding ו-ButtonDefaults.minimumVerticalListContentPadding), כדי ש-TransformingLazyColumn ישתמש לפחות במרווח הפנימי המומלץ בחלק העליון והתחתון כשהפריטים האלה מופיעים בקצה הרשימה.
  • השימוש ב-ListHeader לפריט הראשון ברשימה, במקום ב-composable פשוט של Text.

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

  • ספריית Horologist – מספקת כלים שעוזרים לפתח אפליקציות מותאמות אישית וייחודיות ל-Wear OS.
  • הדוגמה ComposeStarter – דוגמה שממחישה את העקרונות שמפורטים במדריך הזה.
  • האפליקציה לדוגמה JetCaster – דוגמה מורכבת יותר לפיתוח אפליקציה שמתאימה לגדלים שונים של מסכים, באמצעות ספריית Horologist.

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

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

ההשפעה של גודל המכשיר ושינוי גודל הגופן

ההשפעה של גדלים שונים של מכשירים ושינוי קנה המידה של הגופן.

תיבות דו-שיח

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

במסכים בהתאמה אישית יכול להיות שיהיה צורך בפריסות ללא גלילה

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

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

יצירת חוויות שונות באמצעות נקודות עצירה (breakpoint)

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

const val LARGE_DISPLAY_BREAKPOINT = 225

@Composable
fun isLargeDisplay() =
    LocalConfiguration.current.screenWidthDp >= LARGE_DISPLAY_BREAKPOINT

// ...
// ... use in your Composables:
    if (isLargeDisplay()) {
        // Show additional content.
    } else {
        // Show content only for smaller displays.
    }
    // ...

ההנחיות לעיצוב ממחישות עוד הזדמנויות כאלה.

בודקים שילובים של גודלי מסך וגופנים באמצעות תצוגות מקדימות

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

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

חשוב להטמיע תצוגות מקדימות באמצעות WearPreviewDevices ו-WearPreviewFontScales בכל המסכים באפליקציה. פרטים מלאים על הגדרת תצוגות מקדימות ב-Wear OS, מפרטי חומרה בהתאמה אישית ותצוגה מקדימה של רשימות בגלילה זמינים במאמר תצוגה מקדימה של ממשק המשתמש ב-Compose ל-Wear OS.

@WearPreviewDevices
@WearPreviewFontScales
@Composable
fun ComposeListPreview() {
    ComposeList()
}

בדיקת צילומי מסך

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

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

הדוגמאות שלנו משתמשות ב-Roborazzi לבדיקת צילומי מסך:

  1. מגדירים את קובצי build.gradle של הפרויקט והאפליקציה כך שישתמשו ב-Roborazzi.
  2. יוצרים בדיקת צילום מסך לכל מסך באפליקציה. לדוגמה, הקוד הבא מציג בדיקת צילום מסך למסך שמכיל רשימה:
@RunWith(ParameterizedRobolectricTestRunner::class)
class ComposeListScreenTest(
    override val device: WearDevice
) : WearScreenshotTest() {
    override val tolerance = 0.02f

    @Test
    fun myScreenTest() =
        runTest {
            AppScaffold {
                ComposeList()
            }
        }

    companion object {
        @JvmStatic
        @ParameterizedRobolectricTestRunner.Parameters
        fun devices() = WearDevice.entries
    }
}

כמה נקודות שחשוב לשים לב אליהן:

  • WearDevice.entries מכיל הגדרות של מכשירי Wear OS הפופולריים ביותר, כדי שהבדיקות יופעלו על מגוון מייצג של גדלי מסכים.

יצירת תמונות זהב

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

./gradlew recordRoborazziDebug

אימות התמונות

כדי לאמת את השינויים מול קובצי אימג' קיימים, מריצים את הפקודה הבאה בטרמינל:

./gradlew verifyRoborazziDebug

דוגמה מלאה לבדיקת צילומי מסך מופיעה בדוגמה של ComposeStarter.