החל מ-Android 12, ה-API של SplashScreen
מאפשר להפעיל אפליקציות עם אנימציה, כולל תנועה אל תוך האפליקציה בזמן ההפעלה, מסך פתיחה שבו מוצג סמל האפליקציה ומעבר אל האפליקציה עצמה. SplashScreen
הוא Window
ולכן מכסה Activity
.
חוויית מסך הפתיחה כוללת רכיבי עיצוב סטנדרטיים בכל הפעלה של האפליקציה, אבל אפשר גם להתאים אישית את המסך כדי לשמור על המיתוג הייחודי של האפליקציה.
בנוסף לשימוש ב-API של פלטפורמת SplashScreen
, אפשר גם להשתמש בספריית התאימות SplashScreen
, שמקיפה את ה-API של SplashScreen
.
איך פועל מסך הפתיחה
כשמשתמש מפעיל אפליקציה בזמן שהתהליך של האפליקציה לא פועל (התחלה קרה) או שה-Activity
לא נוצר (התחלה חמה), מתרחשים האירועים הבאים:
המערכת מציגה את מסך הפתיחה באמצעות עיצובים ואנימציות שאתם מגדירים.
כשהאפליקציה מוכנה, מסך הפתיחה נסגר והאפליקציה מוצגת.
מסך הפתיחה לא מוצג אף פעם במהלך הפעלה מחדש.
הרכיבים והמנגנון של מסך הפתיחה
האלמנטים של מסך הפתיחה מוגדרים באמצעות קובצי משאבים של XML בקובץ המניפסט של Android. לכל אלמנט יש גרסה למצב בהיר ולמצב כהה.
הרכיבים שניתן להתאים אישית במסך הפתיחה הם סמל האפליקציה, הרקע של הסמל והרקע של החלון:
כדאי להביא בחשבון את הרכיבים הבאים, שמוצגים באיור 2:
1 סמל האפליקציה חייב להיות פריט גרפי וקטורי שניתן לשרטוט. הוא יכול להיות סטטי או מונפש. אורך האנימציה יכול להיות בלתי מוגבל, אבל מומלץ לא לחרוג מ-1,000 אלפיות השנייה. סמל מרכז האפליקציות הוא ברירת המחדל.
2 הרקע של הסמל הוא אופציונלי ושימושי אם אתם צריכים יותר ניגודיות בין הסמל לבין הרקע של החלון. אם משתמשים בסמל מותאם, הרקע שלו מוצג אם יש מספיק ניגודיות בינו לבין הרקע של החלון.
3 בדומה לסמלים מותאמים, שליש מחזית התמונה מוסתר.
4 הרקע של החלון מורכב מצבע אטום אחד. אם רקע החלון מוגדר בצבע פשוט, הוא ישמש כברירת מחדל אם המאפיין לא מוגדר.
המימדים של מסך הפתיחה
הסמל של מסך הפתיחה משתמש באותם מפרטים כמו סמלים מותאמים, כדלקמן:
- תמונה ממותגת: הגודל שלה חייב להיות 200×80dp.
- סמל אפליקציה עם רקע של סמל: הגודל צריך להיות 240×240 dp ולהתאים אותו לעיגול בקוטר של 160dp.
- סמל אפליקציה ללא רקע: הגודל צריך להיות 288 על 288 dp, והסמל צריך להתאים לעיגול בקוטר 192 dp.
לדוגמה, אם הגודל המלא של תמונה הוא 300×300dp, הסמל צריך להתאים לתוך עיגול בקוטר של 200dp. כל מה שמחוץ לעיגול הופך לבלתי נראה (מוסתיר).
אנימציות במסך הפתיחה וסדר ההפעלה
בדרך כלל יש זמן אחזור נוסף בהפעלה של אפליקציה במצב התחלתי (cold start). הוספת סמל מונפש למסך הפתיחה מושכת את העין ומספקת חוויה איכותית יותר. מחקר משתמשים מראה שזמן ההפעלה המשוער קצר יותר כשמוצגת אנימציה.
אנימציה של מסך פתיחה מוטמעת ברכיבים של רצף ההפעלה, כפי שמוצג באיור 4.
אנימציית כניסה: היא מורכבת מתצוגת המערכת ועד למסך הפתיחה. הוא נשלט על ידי המערכת ולא ניתן להתאים אותו אישית.
מסך הפתיחה (מוצג במהלך החלק 'המתנה' ברצף): אפשר להתאים אישית את מסך הפתיחה, כך שתוכלו לספק אנימציה של הלוגו ורכיבי מיתוג משלכם. כדי שהמינוי יפעל כראוי, הוא צריך לעמוד בדרישות שמפורטות בדף הזה.
יציאה מהאנימציה: האנימציה שמסתירה את מסך הפתיחה. אם רוצים להתאים אישית את התפריט, משתמשים ב
SplashScreenView
ובסמל שלו. אפשר להפעיל בהם כל אנימציה, עם הגדרות של טרנספורמציה, שקיפות וצבע. במקרה כזה, מסירים ידנית את מסך הפתיחה כשהאנימציה תסתיים.
כשמריצים את אנימציית הסמל, השקת האפליקציה מאפשרת לדלג על התהליך במקרים שבהם האפליקציה מוכנה מוקדם יותר. האפליקציה מפעילה את onResume()
או שהזמן לטיימר של מסך הפתיחה פג באופן אוטומטי, לכן חשוב לוודא שאפשר לדלג על התנועה בנוחות. אפשר לסגור את מסך הפתיחה באמצעות onResume()
רק כשהאפליקציה יציבה מבחינה חזותית, כך שאין צורך בספינרים נוספים. הצגת ממשק לא שלם עלולה ליצור קשיים בקרב המשתמשים וליצור רושם של חוסר חיזוי או חוסר ליטוש.
הדרישות לגבי אנימציה במסך הפתיחה
מסך הפתיחה צריך לעמוד במפרטים הבאים:
הגדרת צבע רקע של חלון אחד ללא שקיפות. התמיכה במצב יום ולילה זמינה באמצעות ספריית התאימות
SplashScreen
.צריך לוודא שהסמל האנימציה עומד במפרטים הבאים:
- פורמט: הסמל צריך להיות קובץ XML של AnimatedVectorDrawable (AVD).
- מידות: סמל AVD חייב להיות גדול פי ארבע מסמל מותאם, באופן הבא:
- שטח הסמל חייב להיות 432dp – כלומר, פי ארבעה משטח של 108dp של סמל אדפטיבי ללא מסכה.
- שני השלישים הפנימי של התמונה גלויים בסמל מרכז האפליקציות, וצריכים להיות בגודל של 288 dp. במילים אחרות, הם צריכים להיות בגודל של פי 4 מ- 72 dp שמרכיבים את אזור המסכה הפנימי של סמל אדפטיבי.
- משך זמן: מומלץ לא לחרוג מ-1,000 אלפיות השנייה בטלפונים. אפשר להשתמש בהפעלה עם עיכוב, אבל העיכוב לא יכול להיות ארוך מ-166 אלפיות שנייה. אם זמן ההפעלה של האפליקציה ארוך מ-1,000 אלפיות שנייה, מומלץ להשתמש באנימציה בלופ.
כדאי לקבוע זמן מתאים לסגירת מסך הפתיחה, שמתרחש בזמן שהאפליקציה מציירת את הפריים הראשון שלה. אפשר להתאים אישית את האפשרות הזו בהתאם לתיאור בקטע הצגת מסך הפתיחה למשך זמן ארוך יותר.
משאבים של מסך פתיחה
כדאי להוריד את חבילת ההתחלה לדוגמה, שבה מוסבר איך ליצור אנימציה, לעצב אותה ולייצא אותה לקובץ 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 ואילך.
משתמשים ב-
windowSplashScreenBackground
כדי למלא את הרקע בצבע אחד ספציפי:<item name="android:windowSplashScreenBackground">@color/...</item>
משתמשים ב-
windowSplashScreenAnimatedIcon
כדי להחליף את הסמל במרכז החלון הפותח.באפליקציות שמטרגטות את Android 12 (רמת API 32) בלבד, צריך לבצע את הפעולות הבאות:
אם אפשר להציג אנימציה של האובייקט ולצייר אותו באמצעות
AnimationDrawable
ו-AnimatedVectorDrawable
, מגדירים אתwindowSplashScreenAnimationDuration
להפעלת האנימציה בזמן הצגת החלון ההתחלתי. לא חובה לעשות זאת ב-Android 13, כי משך הזמן נקבע ישירות על סמךAnimatedVectorDrawable
.<item name="android:windowSplashScreenAnimatedIcon">@drawable/...</item>
משתמשים ב-
windowSplashScreenAnimationDuration
כדי לציין את משך האנימציה של סמל מסך הפתיחה. ההגדרה הזו לא משפיעה על משך הזמן בפועל שבו מסך הפתיחה מוצג, אבל אפשר לאחזר אותה כשמתאימים אישית את האנימציה של יציאה ממסך הפתיחה באמצעותSplashScreenView.getIconAnimationDuration
. פרטים נוספים זמינים בקטע הבא בנושא הצגת מסך הפתיחה למשך זמן ארוך יותר.<item name="android:windowSplashScreenAnimationDuration">1000</item>
משתמשים ב-
windowSplashScreenIconBackgroundColor
כדי להגדיר רקע מאחורי הסמל של מסך הפתיחה. האפשרות הזו מועילה אם אין מספיק ניגודיות בין הרקע של החלון לבין הסמל.<item name="android:windowSplashScreenIconBackgroundColor">@color/...</item>
אפשר להשתמש ב-
windowSplashScreenBrandingImage
כדי להגדיר תמונה שתוצג בתחתית מסך הפתיחה. עם זאת, מומלץ לא להשתמש בתמונה של מיתוג בהתאם להנחיות התכנון.<item name="android:windowSplashScreenBrandingImage">@drawable/...</item>
אפשר להשתמש ב-
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; }
מקורות מידע נוספים
- העברת ההטמעה הקיימת של מסך הפתיחה ל-Android 12 ואילך
- עכשיו ב-Android, שמציגה הטמעה של מסך פתיחה בעולם האמיתי