מסכי פתיחה

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

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

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

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

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

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

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

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

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

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

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

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

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

נבחן את הרכיבים הבאים, שמוצגים באיור 2:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    • פורמט: הסמל חייב להיות AnimatedVectorDrawable (AVD) XML.
    • מידות: סמל AVD חייב להיות גדול פי ארבע מסמל מותאם, באופן הבא:
      • אזור הסמל חייב להיות 432dp - במילים אחרות, ארבע פעמים שטח של 108 dp של סמל מותאם ללא מסכה.
      • שני השלישים הפנימיים של התמונה גלויים בסמל במרכז האפליקציות, והם צריכים להיות בגודל 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();
    });
}

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

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