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

קומפוזיציה מוגדרת על ידי פונקציה ומסומנת באמצעות @Composable:

@Composable
fun SimpleComposable() {
    Text("Hello World")
}

רכיב טקסט פשוט שמכיל את המילים "Hello
World"

כדי להפעיל תצוגה מקדימה של רכיב ה-Composable הזה, צריך ליצור עוד רכיב Composable עם ההערות @Composable ו-@Preview. הרכיב הקומפוזבילי החדש עם ההערות מכיל עכשיו את הרכיב הקומפוזבילי שיצרתם בהתחלה, SimpleComposable:

@Preview
@Composable
fun SimpleComposablePreview() {
    SimpleComposable()
}

ההערה @Preview אומרת ל-Android Studio שרכיב ה-Composable הזה צריך להיות מוצג בתצוגת העיצוב של הקובץ הזה. כשעורכים את התצוגה המקדימה של הרכיבים, אפשר לראות את העדכונים בזמן אמת.

‫GIF שמציג עדכונים בזמן אמת באמצעות תצוגה מקדימה של כתיבת קוד

אפשר להוסיף פרמטרים לקוד באופן ידני כדי להתאים אישית את האופן שבו Android Studio מעבד את @Preview. אפשר אפילו להוסיף את ההערה @Preview לאותה פונקציה כמה פעמים כדי לראות תצוגה מקדימה של רכיב שאפשר להרכיב עם מאפיינים שונים.

אחד מהיתרונות העיקריים של שימוש ברכיבים קומפוזביליים @Preview הוא הימנעות מהסתמכות על האמולטור ב-Android Studio. אתם יכולים לשמור את ההפעלה של האמולטור, שדורשת הרבה זיכרון, לשינויים סופיים יותר במראה ובתחושה, ולהשתמש ביכולת של @Preview לבצע ולבדוק שינויים קטנים בקוד בקלות.

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

הגדרת @Preview

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

מידות

כברירת מחדל, המידות של @Preview נבחרות באופן אוטומטי כדי להתאים לתוכן. כדי להגדיר את המאפיינים באופן ידני, מוסיפים את הפרמטרים heightDp ו-widthDp. הערכים האלה כבר מפורשים כ-dp, ולכן אין צורך להוסיף להם את .dp:

@Preview(widthDp = 50, heightDp = 50)
@Composable
fun SquareComposablePreview() {
    Box(Modifier.background(Color.Yellow)) {
        Text("Hello World")
    }
}

ריבוע צהוב עם המילים Hello World (שלום עולם)

תצוגה מקדימה של צבע דינמי

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

שימוש במכשירים שונים

ב-Android Studio Flamingo, אפשר לערוך את הפרמטר device של הערת ה-Preview כדי להגדיר קומפוזיציות במכשירים שונים.

דוגמה לפונקציה קומפוזבילית

כשהפרמטר device הוא מחרוזת ריקה (@Preview(device = "")), אפשר להפעיל את ההשלמה האוטומטית על ידי לחיצה על Ctrl + Space. לאחר מכן, אפשר להגדיר את הערכים של כל פרמטר.

עריכת הפונקציה לדוגמה

מההשלמה האוטומטית, אפשר לבחור כל אפשרות של מכשיר מהרשימה – לדוגמה, @Preview(device = "id:pixel_4"). לחלופין, אפשר להזין מכשיר מותאם אישית על ידי בחירה באפשרות spec:width=px,height=px,dpi=int… כדי להגדיר את הערכים הנפרדים של כל פרמטר.

רשימת
המפרטים

כדי להחיל את השינוי, לוחצים על Enter. כדי לבטל, לוחצים על Esc.

אם מגדירים ערך לא תקין, ההצהרה מסומנת בקו אדום מתחתיה, ויכול להיות שיהיה תיקון זמין (‎Alt + Enter (⌥ + ⏎ ב-macOS) > החלפה ב…). הבדיקה מנסה לספק תיקון שדומה ככל האפשר לקלט שלכם.

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

לוקאל

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

@Preview(locale = "fr-rFR")
@Composable
fun DifferentLocaleComposablePreview() {
    Text(text = stringResource(R.string.greeting))
}

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

הגדרת צבע הרקע

כברירת מחדל, הרקע של הרכיב המורכב שקוף. כדי להוסיף רקע, מוסיפים את הפרמטרים showBackground ו-backgroundColor. חשוב לזכור ש-backgroundColor הוא ערך ARGB Long, ולא ערך Color:

@Preview(showBackground = true, backgroundColor = 0xFF00FF00)
@Composable
fun WithGreenBackground() {
    Text("Hello World")
}

מלבן ירוק עם המילים Hello World

ממשק משתמש של המערכת

אם רוצים להציג את סרגלי הסטטוס והפעולות בתצוגה מקדימה, מוסיפים את הפרמטר showSystemUi:

@Preview(showSystemUi = true)
@Composable
fun DecoratedComposablePreview() {
    Text("Hello World")
}

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

מצב ממשק המשתמש

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

ממשק המשתמש של יצירת התצוגה המקדימה

LocalInspectionMode

אפשר לקרוא את הקוד מ-LocalInspectionMode CompositionLocal כדי לראות אם הרכיב ניתן להרכבה מוצג בתצוגה מקדימה (בתוך רכיב שאפשר לבדוק). אם הקומפוזיציה עוברת רינדור בתצוגה מקדימה, הערך של LocalInspectionMode.current הוא true. המידע הזה מאפשר לכם להתאים אישית את התצוגה המקדימה. לדוגמה, אתם יכולים להציג תמונה של placeholder בחלון התצוגה המקדימה במקום להציג נתונים אמיתיים.

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

@Composable
fun GreetingScreen(name: String) {
    if (LocalInspectionMode.current) {
        // Show this text in a preview window:
        Text("Hello preview user!")
    } else {
        // Show this text in the app:
        Text("Hello $name!")
    }
}

אינטראקציה עם @Preview

ב-Android Studio יש תכונות שמאפשרות לכם לנהל אינטראקציה עם התצוגות המקדימות שהגדרתם. האינטראקציה הזו עוזרת לכם להבין את התנהגות התצוגות המקדימות בזמן הריצה, ומאפשרת לכם לנווט בממשק המשתמש בצורה טובה יותר באמצעות תצוגות מקדימות.

מצב אינטראקטיבי

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

המשתמש לוחץ על הלחצן 'אינטראקטיבי' בתצוגה המקדימה

סרטון שבו המשתמש מקיים אינטראקציה עם תצוגה מקדימה

ניווט בקוד ומתארים הניתנים להרכבה

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

המשתמש מעביר את העכבר מעל תצוגה מקדימה, וכתוצאה מכך Studio מציג את קווי המתאר של רכיבי ה-Composable שלה

הפעלת תצוגה מקדימה

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

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

המשתמש לוחץ על התצוגה המקדימה

סרטון של משתמש שמפעיל תצוגה מקדימה במכשיר

העתקת @Preview רנדר

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

המשתמש לוחץ על תצוגה מקדימה כדי להעתיק אותה כתמונה.

כמה תצוגות מקדימות של אותה הערה @Preview

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

תבניות של תצוגה מקדימה מרובה

androidx.compose.ui:ui-tooling-preview 1.6.0-alpha01+ כולל תבניות Multipreview API: ‏ @PreviewScreenSizes,‏ @PreviewFontScales,‏ @PreviewLightDark ו-@PreviewDynamicColors, כך שבאמצעות הערה אחת תוכלו לראות תצוגה מקדימה של ממשק המשתמש של Compose בתרחישים נפוצים.

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

יצירת הערות מותאמות אישית בתצוגה מקדימה מרובה

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

מתחילים ביצירת סוג הערה מותאם אישית:

@Preview(
    name = "small font",
    group = "font scales",
    fontScale = 0.5f
)
@Preview(
    name = "large font",
    group = "font scales",
    fontScale = 1.5f
)
annotation class FontScalePreviews

אפשר להשתמש בהערה המותאמת אישית הזו עבור פונקציות ה-Composable של התצוגה המקדימה:

@FontScalePreviews
@Composable
fun HelloWorldPreview() {
    Text("Hello World")
}

כרטיסיית העיצוב ב-Android Studio שבה מוצג קומפוזבל עם גופן קטן וגדול

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

@Preview(
    name = "Spanish",
    group = "locale",
    locale = "es"
)
@FontScalePreviews
annotation class CombinedPreviews

@CombinedPreviews
@Composable
fun HelloWorldPreview2() {
    MaterialTheme { Surface { Text(stringResource(R.string.hello_world)) } }
}

הכרטיסייה 'עיצוב' ב-Android Studio שבה מוצג רכיב קומפוזבילי בכל התצורות

האופי של התצוגה המקדימה המרובה – וגם של התצוגה המקדימה הרגילה – מאפשר לכם לבדוק באופן מקיף יותר הרבה מאפיינים של פרויקטים בקנה מידה גדול יותר.

@Preview וקבוצות גדולות של נתונים

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

@Preview
@Composable
fun UserProfilePreview(
    @PreviewParameter(UserPreviewParameterProvider::class) user: User
) {
    UserProfile(user)
}

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

class UserPreviewParameterProvider : PreviewParameterProvider<User> {
    override val values = sequenceOf(
        User("Elise"),
        User("Frank"),
        User("Julia")
    )
}

הפעולה הזו יוצרת תצוגה מקדימה אחת לכל רכיב נתונים ברצף:

תצוגות מקדימות שמציגות רכיבים קומפוזביליים של Elise, ‏ Frank ו-Julia

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

@Preview
@Composable
fun UserProfilePreview2(
    @PreviewParameter(UserPreviewParameterProvider::class, limit = 2) user: User
) {
    UserProfile(user)
}

תצוגות מקדימות באמצעות @PreviewParameter מקבלות שם כברירת מחדל לפי אינדקס הפרמטר ושם המאפיין (user 0,‏ user 1,‏ user 2 וכן הלאה), ולכן קשה להבחין ביניהן. כדי לשפר את הבהירות של התצוגה המקדימה, אפשר לספק שמות תצוגה מותאמים אישית לכל תצוגה מקדימה על ידי החלפת getDisplayName() ב-PreviewParameterProvider. ההגדרה הזו עוזרת להבחין בין וריאציות שונות של נתונים או בין מצבים שונים של ממשק המשתמש. לדוגמה, אפשר לתת תווית לתצוגות מקדימות על סמך נתוני הקלט:

class UserAgePreviewParameterProvider : PreviewParameterProvider<User> {
    // Using a List internally for efficient index-based access
    private val userList = listOf(
        User(name = "Elise", age = 30),
        User(name = "Frank", age = 31),
        User(name = "Julia", age = 40)
    )

    override val values = userList.asSequence()

    override fun getDisplayName(index: Int): String? {
        // Return null or an empty string to use the default index-based name
        val user = userList.getOrNull(index) ?: return null
        return "${user.name} - ${user.age}"
    }
}

תצוגות מקדימות עם שמות מוצגים בהתאמה אישית שמציגות את Elise - 30, Frank - 31 ו-Julia - 40 composables

יצירת תצוגה מקדימה בעזרת AI

סוכן ה-AI ב-Android Studio יכול ליצור באופן אוטומטי תצוגות מקדימות של Compose לרכיבי ה-Composable. לוחצים לחיצה ימנית על פונקציה קומפוזבילית ובוחרים באפשרות AI > Generate Preview for [Composable name] (AI > יצירת תצוגה מקדימה עבור [שם הפונקציה הקומפוזבילית]). הסוכן מנתח את הקומפוזיציה כדי ליצור את @Previewהקוד הסטנדרטי עם הפרמטרים הנכונים, וכך עוזר לכם לוודא במהירות שממשק המשתמש מוצג כמו שציפיתם.

יצירת תצוגה מקדימה של הטיוטה באמצעות AI

סיווג ההערה @Preview

תמיד אפשר להקיש על Ctrl או על ‎⌘ + click על ההערה @Preview ב-Android Studio כדי לראות רשימה מלאה של הפרמטרים שאפשר לשנות כשמתאימים אישית את התצוגה המקדימה.

annotation class Preview(
    val name: String = "",
    val group: String = "",
    @IntRange(from = 1) val apiLevel: Int = -1,
    val widthDp: Int = -1,
    val heightDp: Int = -1,
    val locale: String = "",
    @FloatRange(from = 0.01) val fontScale: Float = 1f,
    val showSystemUi: Boolean = false,
    val showBackground: Boolean = false,
    val backgroundColor: Long = 0,
    @UiMode val uiMode: Int = 0,
    @Device val device: String = Devices.DEFAULT,
    @Wallpaper val wallpaper: Int = Wallpapers.NONE,
)

מגבלות ושיטות מומלצות

‫Android Studio מריץ קוד של תצוגות מקדימות ישירות באזור התצוגה המקדימה. לא צריך להריץ אמולטור או מכשיר פיזי כי הוא משתמש בחלק מועבר של מסגרת Android שנקרא Layoutlib. ‫Layoutlib היא גרסה מותאמת אישית של מסגרת Android, שנועדה לפעול מחוץ למכשירי Android. המטרה של הספרייה היא לספק תצוגה מקדימה של פריסה ב-Android Studio שדומה מאוד לרינדור שלה במכשירים.

הגבלות על תצוגות מקדימות

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

  • אין גישה לרשת
  • אין גישה לקובץ
  • יכול להיות שחלק מממשקי ה-API של Context לא יהיו זמינים באופן מלא

תצוגה מקדימה וViewModels

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

כשמנסים להציג בתצוגה מקדימה קומפוזבל עם ViewModel, ‏ Android Studio מציג שגיאה כשמעבדים את הקומפוזבל הספציפי:

חלונית הבעיות ב-Android Studio עם ההודעה Failed to instantiate a `ViewModel`

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

@Composable
fun AuthorScreen(viewModel: AuthorViewModel = viewModel()) {
  AuthorScreen(
    name = viewModel.authorName,
    // ViewModel sends the network requests and makes posts available as a state
    posts = viewModel.posts
  )
}

@Composable
fun AuthorScreen(
  name: NameLabel,
  posts: PostsList
) {
  // ...
}

@Preview
@Composable
fun AuthorScreenPreview(
  // You can use some sample data to preview your composable without the need to construct the ViewModel
  name: String = sampleAuthor.name,
  posts: List<Post> = samplePosts[sampleAuthor]
) {
  AuthorScreen(
      name = NameLabel(name),
      posts = PostsList(posts)
  )
}

מקורות מידע נוספים

  • בבלוג Compose Tooling אפשר לקרוא מידע נוסף על האופן שבו Android Studio מקדם @Previewנוחות שימוש, ולקבל טיפים נוספים לשימוש בכלים.
  • הנחיות לגבי התכונה 'תצוגות' בגרסה הקודמת של Looker זמינות במאמר פיתוח פריסה באמצעות תצוגות.