מסכי פתיחה

החל מ-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×80dp.
  • סמל אפליקציה עם רקע של סמל: הגודל צריך להיות 240 על 240dp, והסמל צריך להתאים לתוך עיגול בקוטר 160dp.
  • סמל אפליקציה ללא רקע: הגודל צריך להיות 288 על 288dp, והסמל צריך להתאים לעיגול בקוטר 192dp.

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

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

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

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

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

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

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

  3. אנימציית יציאה: היא מורכבת מהאנימציה שמסתירה את מסך הפתיחה. אם רוצים להתאים אישית את התפריט, משתמשים ב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:

Groovy

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();
    });
}

בתחילת הקריאה החוזרת הזו, מתחילה ההפעלה של החפץ הניתן לציור של וקטור מונפש במסך הפתיחה. בהתאם למשך ההפעלה של האפליקציה, יכול להיות שה-drawable יהיה באמצע האנימציה שלו. אפשר להשתמש ב-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;
}

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