מסכי פתיחה

החל מ-Android 12, ה-API של SplashScreen מאפשר לאפליקציות להיפתח עם אנימציה, כולל תנועה בתוך האפליקציה בזמן ההפעלה, מסך פתיחה שבו מוצג סמל האפליקציה ומעבר לאפליקציה עצמה. SplashScreen הוא Window, ולכן הוא כולל Activity.

איור 1. מסך פתיחה.

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

בנוסף לשימוש ב-API של פלטפורמת SplashScreen, אתם יכולים להשתמש גם בספריית התאימות SplashScreen, שעוטפת את ה-API של SplashScreen.

איך פועל מסך הפתיחה

כשמשתמש מפעיל אפליקציה בזמן שהתהליך של האפליקציה לא פועל (הפעלה קרה) או שה-Activity לא נוצר (הפעלה חמה), מתרחשים האירועים הבאים:

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

  2. כשהאפליקציה מוכנה, מסך הפתיחה נסגר והאפליקציה מוצגת.

מסך הפתיחה אף פעם לא מוצג במהלך הפעלה חמה.

רכיבים ומכניקה של מסך הפתיחה

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

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

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

אלה הרכיבים שמוצגים באיור 2:

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

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

3 כמו בסמלים הניתנים להתאמה, שליש מהחזית מוסתר.

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

מידות מסך הפתיחה

הסמל של מסך הפתיחה משתמש באותם מפרטים כמו סמלים הניתנים להתאמה, כפי שמפורט בהמשך:

  • תמונה ממותגת: הגודל צריך להיות 200×80 dp.
  • סמל אפליקציה עם רקע: הסמל צריך להיות בגודל 240×240dp ולהתאים לעיגול בקוטר 160dp.
  • סמל האפליקציה ללא רקע: הסמל צריך להיות בגודל 288×288 dp ולהתאים לעיגול בקוטר 192 dp.

לדוגמה, אם הגודל המלא של התמונה הוא ‎300×300 dp, הסמל צריך להתאים לעיגול בקוטר של ‎200 dp. כל מה שמחוץ לעיגול הופך לבלתי נראה (מוסתר).

תמונה שמראה מידות שונות של סמלים עם רקע אטום ורקע שקוף
איור 3. מידות הסמל של מסך הפתיחה לרקעים אחידים ושקופים, בהתאמה.

אנימציות של מסך פתיחה ורצף ההפעלה

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

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

תמונה שבה מוצג רצף ההפעלה ב-12 פריימים עוקבים, החל מהקשה על סמל מרכז האפליקציות ועד שהוא ממלא את המסך כשהוא גדל
איור 4. רצף ההשקה.
  1. אנימציית כניסה: המעבר מתצוגת המערכת למסך הפתיחה. הוא נשלט על ידי המערכת ואי אפשר להתאים אותו אישית.

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

  3. אנימציית יציאה: האנימציה שמסתירה את מסך הפתיחה. אם רוצים להתאים אישית את ה-API, משתמשים ב-SplashScreenView ובסמל שלו. אפשר להפעיל עליהם כל אנימציה, עם הגדרות לשינוי צורה, שקיפות וצבע. במקרה כזה, צריך להסיר ידנית את מסך הפתיחה כשהאנימציה מסתיימת.

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

הדרישות לגבי אנימציה של מסך פתיחה

מסך הפתיחה צריך לעמוד במפרטים הבאים:

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

  • חשוב לוודא שהסמל המונפש עומד בדרישות הבאות:

    • פורמט: הסמל חייב להיות קובץ XML מסוג AnimatedVectorDrawable (AVD).
    • מידות: סמל AVD צריך להיות גדול פי ארבעה מסמל שניתן להתאמה, באופן הבא:
      • אזור הסמל חייב להיות בגודל 432dp – כלומר, פי ארבעה מהאזור של 108dp של סמל הניתן להתאמה ללא מסכה.
      • שני השלישים הפנימיים של התמונה גלויים בסמל מרכז האפליקציות, והם צריכים להיות בגודל 288dp – כלומר, פי ארבעה מהגודל של 72dp שמרכיב את האזור הפנימי המוסתר של סמל הניתן להתאמה.
    • משך זמן: מומלץ לא לחרוג מ-1,000 אלפיות השנייה בטלפונים. אפשר להשתמש בהפעלה מושהית, אבל היא לא יכולה להיות ארוכה מ-166 אלפיות השנייה. אם זמן ההפעלה של האפליקציה ארוך מ-1,000 אלפיות השנייה, כדאי להשתמש באנימציה בלופ.
  • צריך לקבוע זמן מתאים לסגירת מסך הפתיחה, שמתרחשת כשהאפליקציה מציגה את הפריים הראשון שלה. אפשר להתאים אישית את מסך הפתיחה, כמו שמתואר בקטע השארת מסך הפתיחה על המסך לפרקי זמן ארוכים יותר.

משאבים למסך הפתיחה

איור 5. דוגמה ל-AVD.

מורידים את ערכת ההתחלה לדוגמה, שמדגימה איך ליצור, לעצב ולייצא אנימציה ל-AVD. הוא כולל את הדברים הבאים:

  • קובץ פרויקט של האנימציה ב-Adobe After Effects.
  • קובץ ה-XML הסופי של ה-AVD שיוצא.
  • קובץ GIF לדוגמה של האנימציה.

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

במדיניות הפרטיות של Google מוסבר איך אנחנו מטפלים בנתונים בשירות הזה.

התאמה אישית של מסך הפתיחה באפליקציה

כברירת מחדל, SplashScreen משתמש ב-windowBackground של העיצוב אם windowBackground הוא בצבע אחיד. כדי להתאים אישית את מסך הפתיחה, מוסיפים מאפיינים לעיצוב של האפליקציה.

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

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

  • השאירו אותו על המסך למשך זמן ארוך יותר.

  • התאמה אישית של האנימציה לסגירת מסך הפתיחה.

שנתחיל?

ספריית הליבה SplashScreen מביאה את מסך הפתיחה של Android 12 לכל המכשירים מ-API 23. כדי להוסיף אותו לפרויקט, מוסיפים את קטע הקוד הבא לקובץ build.gradle:

מגניב

dependencies {
    implementation "androidx.core:core-splashscreen:1.0.0"
}

Kotlin

dependencies {
    implementation("androidx.core:core-splashscreen:1.0.0")
}

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

אפשר לציין את המאפיינים הבאים בעיצוב של Activity כדי להתאים אישית את מסך הפתיחה של האפליקציה. אם כבר יש לכם הטמעה קודמת של מסך פתיחה שמשתמשת במאפיינים כמו android:windowBackground, כדאי לספק קובץ משאבים חלופי ל-Android מגרסה 12 ואילך.

  1. כדי למלא את הרקע בצבע אחד ספציפי, משתמשים ב-windowSplashScreenBackground:

    <item name="android:windowSplashScreenBackground">@color/...</item>
    
  2. משתמשים ב-windowSplashScreenAnimatedIcon כדי להחליף את הסמל במרכז החלון ההתחלתי.

    באפליקציות שמטרגטות ל-Android 12 (רמת API ‏32) בלבד, צריך לבצע את הפעולות הבאות:

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

    <item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
    
  3. משתמשים ב-windowSplashScreenAnimationDuration כדי לציין את משך האנימציה של סמל מסך הפתיחה. ההגדרה הזו לא משפיעה על משך הזמן שבו מסך הפתיחה מוצג בפועל, אבל אפשר לאחזר אותו כשמתאימים אישית את האנימציה של היציאה ממסך הפתיחה באמצעות SplashScreenView.getIconAnimationDuration. למידע נוסף, עיינו בקטע הבא בנושא השארת מסך הפתיחה על המסך לפרקי זמן ארוכים יותר.

    <item name="android:windowSplashScreenAnimationDuration">1000</item>
    
  4. משתמשים ב-windowSplashScreenIconBackgroundColor כדי להגדיר רקע מאחורי הסמל של מסך הפתיחה. האפשרות הזו שימושית אם אין מספיק ניגודיות בין הרקע של החלון לבין הסמל.

    <item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
    
  5. אפשר להשתמש ב- windowSplashScreenBrandingImage כדי להגדיר תמונה שתוצג בתחתית מסך הפתיחה. עם זאת, בהנחיות העיצוב מומלץ לא להשתמש בתמונת מיתוג.

    <item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
    
  6. אתם יכולים להשתמש ב-windowSplashScreenBehavior כדי לציין אם האפליקציה תמיד תציג את הסמל במסך הפתיחה ב-Android מגרסה 13 ואילך. ערך ברירת המחדל הוא 0, שבו הסמל מוצג במסך הפתיחה אם הפעילות שמופעלת מגדירה את splashScreenStyle לערך SPLASH_SCREEN_STYLE_ICON, או פועלת לפי התנהגות המערכת אם הפעילות שמופעלת לא מציינת סגנון. אם אתם מעדיפים שאף פעם לא יוצג מסך פתיחה ריק, ורוצים שתמיד יוצג הסמל המונפש, צריך להגדיר את הערך icon_preferred.

    <item name="android:windowSplashScreenBehavior">icon_preferred</item>
    

השארת מסך הפתיחה על המסך לפרקי זמן ארוכים יותר

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

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

Kotlin

// Create a new event for the activity.
override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // Set the layout for the content view.
    setContentView(R.layout.main_activity)

    // Set up an OnPreDrawListener to the root view.
    val content: View = findViewById(android.R.id.content)
    content.viewTreeObserver.addOnPreDrawListener(
        object : ViewTreeObserver.OnPreDrawListener {
            override fun onPreDraw(): Boolean {
                // Check whether the initial data is ready.
                return if (viewModel.isReady) {
                    // The content is ready. Start drawing.
                    content.viewTreeObserver.removeOnPreDrawListener(this)
                    true
                } else {
                    // The content isn't ready. Suspend.
                    false
                }
            }
        }
    )
}

Java

// Create a new event for the activity.
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Set the layout for the content view.
    setContentView(R.layout.main_activity);

    // Set up an OnPreDrawListener to the root view.
    final View content = findViewById(android.R.id.content);
    content.getViewTreeObserver().addOnPreDrawListener(
            new ViewTreeObserver.OnPreDrawListener() {
                @Override
                public boolean onPreDraw() {
                    // Check whether the initial data is ready.
                    if (mViewModel.isReady()) {
                        // The content is ready. Start drawing.
                        content.getViewTreeObserver().removeOnPreDrawListener(this);
                        return true;
                    } else {
                        // The content isn't ready. Suspend.
                        return false;
                    }
                }
            });
}

התאמה אישית של האנימציה לסגירת מסך הפתיחה

אפשר להתאים אישית את האנימציה של מסך הפתיחה באמצעות Activity.getSplashScreen().

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    splashScreen.setOnExitAnimationListener { splashScreenView ->
        // Create your custom animation.
        val slideUp = ObjectAnimator.ofFloat(
            splashScreenView,
            View.TRANSLATION_Y,
            0f,
            -splashScreenView.height.toFloat()
        )
        slideUp.interpolator = AnticipateInterpolator()
        slideUp.duration = 200L

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.doOnEnd { splashScreenView.remove() }

        // Run your animation.
        slideUp.start()
    }
}

Java

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...

    // Add a callback that's called when the splash screen is animating to the
    // app content.
    getSplashScreen().setOnExitAnimationListener(splashScreenView -> {
        final ObjectAnimator slideUp = ObjectAnimator.ofFloat(
                splashScreenView,
                View.TRANSLATION_Y,
                0f,
                -splashScreenView.getHeight()
        );
        slideUp.setInterpolator(new AnticipateInterpolator());
        slideUp.setDuration(200L);

        // Call SplashScreenView.remove at the end of your custom animation.
        slideUp.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                splashScreenView.remove();
            }
        });

        // Run your animation.
        slideUp.start();
    });
}

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

Kotlin

// Get the duration of the animated vector drawable.
val animationDuration = splashScreenView.iconAnimationDuration
// Get the start time of the animation.
val animationStart = splashScreenView.iconAnimationStart
// Calculate the remaining duration of the animation.
val remainingDuration = if (animationDuration != null && animationStart != null) {
    (animationDuration - Duration.between(animationStart, Instant.now()))
        .toMillis()
        .coerceAtLeast(0L)
} else {
    0L
}

Java

// Get the duration of the animated vector drawable.
Duration animationDuration = splashScreenView.getIconAnimationDuration();
// Get the start time of the animation.
Instant animationStart = splashScreenView.getIconAnimationStart();
// Calculate the remaining duration of the animation.
long remainingDuration;
if (animationDuration != null && animationStart != null) {
    remainingDuration = animationDuration.minus(
            Duration.between(animationStart, Instant.now())
    ).toMillis();
    remainingDuration = Math.max(remainingDuration, 0L);
} else {
    remainingDuration = 0L;
}

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