شاشات البداية

بدءًا من نظام التشغيل Android 12، واجهة برمجة التطبيقات SplashScreen تتيح تشغيل التطبيقات تحتوي على رسوم متحركة، بما في ذلك الحركة داخل التطبيق عند إطلاقه، وشاشة بداية تعرض رمز التطبيق والانتقال إلى التطبيق نفسه. SplashScreen هو Window و وبالتالي تتناول Activity

الشكل 1. شاشة بداية

توفّر تجربة شاشة البداية عناصر تصميم عادية في كل تطبيق إطلاقه، ولكنه قابل للتخصيص أيضًا حتى يحافظ تطبيقك على علامته التجارية الفريدة.

فضلاً عن استخدام واجهة برمجة التطبيقات SplashScreen Platform API، يمكنك أيضًا استخدام SplashScreen ومكتبة متوافقة تضم واجهة برمجة تطبيقات SplashScreen.

طريقة عمل شاشة البداية

عندما يشغّل مستخدم تطبيقًا أثناء تعذُّر تشغيل عملية التطبيق (برد تبدأ) أو Activity تم إنشاؤه (بداية دافئة)، وقوع الأحداث التالية:

  1. يعرض النظام شاشة البداية باستخدام المظاهر وأي صور متحركة التعريف.

  2. عندما يصبح التطبيق جاهزًا، يتم إغلاق شاشة البداية وعرض التطبيق.

لا تظهر شاشة البداية أبدًا أثناء إعادة التشغيل السريع.

عناصر شاشة البداية وآلياتها

يتم تحديد عناصر شاشة البداية من خلال ملفات موارد XML في ملف بيان Android. هناك إصدارات للوضع الفاتح والوضع الداكن لكل عنصر.

تتكون العناصر القابلة للتخصيص في شاشة البداية من رمز التطبيق ورمزه وخلفية النافذة والخلفية:

صورة تعرض العناصر المضمَّنة في شاشة البداية
الشكل 2. عناصر شاشة البداية القابلة للتخصيص الشاشة.

ضع في الاعتبار العناصر التالية، الموضحة في الشكل 2:

1 يجب أن يكون رمز التطبيق متجهًا قابلاً للرسم. أُنشأها جون هنتر، الذي كان متخصصًا يمكن أن تكون ثابتة أو متحركة. رغم أن الرسوم المتحركة يمكن أن يكون لها مدة غير محدودة، وننصحك بعدم تجاوز 1,000 مللي ثانية. ويكون رمز مشغّل التطبيقات هو الرمز التلقائي.

2 تكون خلفية الرمز اختيارية ومفيدة في حال فأنت بحاجة إلى مزيد من التباين بين الأيقونة وخلفية النافذة. إذا كنت تستخدم الرمز التكيُّفي، إذا كان هناك تباين كافٍ مع خلفية النافذة.

3 كما هو الحال مع الرموز التكيُّفية، يعمل ثلث المقدمة بشكل مخفي.

4 تتألّف خلفية النافذة من عنصر بلون غير شفاف. إذا تم ضبط خلفية النافذة وكان لونها عاديًا، سيتم استخدامها. بشكل تلقائي إذا لم يتم ضبط السمة.

أبعاد شاشة البداية

يستخدم رمز شاشة البداية المواصفات نفسها الرموز التكيفية، على النحو التالي:

  • الصورة ذات العلامة التجارية: يجب أن يكون حجمها 200×80 بكسل مستقل الكثافة.
  • رمز التطبيق مع خلفية رمزية: يجب أن يبلغ حجم هذا الرمز 240×240 بكسل مستقل الكثافة وأن يتناسب داخل دائرة 160 بكسل مستقل الكثافة في القطر.
  • رمز التطبيق بدون خلفية رمز: يجب أن يكون حجمه 288×288 بكسل مستقل الكثافة (dp) وأن تتناسب مع دائرة يبلغ قطرها 192 بكسل مستقل الكثافة.

على سبيل المثال، إذا كان الحجم الكامل للصورة هو 300×300 بكسل مستقل الكثافة، يجب أن يكون الرمز مناسبًا داخل دائرة يبلغ قطرها 200 وحدة بكسل مستقلة الكثافة. يتحول كل شيء خارج الدائرة غير مرئية (مخفية).

صورة تعرض أبعادًا مختلفة لرمز الخلفية الشفافة
الشكل 3. أبعاد رمز شاشة البداية في خلفيات شفافة وشفافة على التوالي.

الصور المتحركة في شاشة البداية وتسلسل الإطلاق

غالبًا ما يرتبط وقت الاستجابة الإضافي بتشغيل تطبيق على البارد. تحظى إضافة رمز متحرك إلى شاشة البداية بجاذبية جمالية واضحة تجربة مميزة أكثر. تشير أبحاث المستخدم إلى أن بدء التشغيل وقت أقل عند عرض رسم متحرك.

يتم تضمين رسم متحرك لشاشة البداية ضمن مكونات تسلسل الإطلاق، مثل كما هو موضح في الشكل 4.

صورة تعرض تسلسل الإطلاق في اثني عشر إطارًا متتاليًا، تبدأ برمز مشغّل التطبيقات الذي يتم النقر عليه وملء الشاشة عند تكبيرها
الشكل 4. تسلسل الإطلاق
  1. إدخال حركة: تتألف من طريقة عرض النظام إلى شاشة البداية. أُنشأها جون هنتر، الذي كان متخصصًا تحت تحكّم النظام ولا يمكن تخصيصها

  2. شاشة البداية (تظهر في جزء "الانتظار" من التسلسل): بداية تخصيص شاشتك، مما يتيح لك تقديم صورة متحركة لشعارك الهوية البصرية للعلامة التجارية. أن يستوفي المتطلبات الموضحة في هذه الصفحة لتعمل بشكل صحيح.

  3. الخروج من الرسم المتحرك: يتكوّن من الرسم المتحرك الذي يخفي شاشة البداية. إذا أردت تخصيصه، استخدِم SplashScreenView و . يمكنك تشغيل أي رسم متحرك عليها، مع إعدادات التحويل والتعتيم واللون. في هذه الحالة، قم بإزالة شاشة البداية يدويًا عندما الانتهاء من الرسوم المتحركة.

عند تشغيل الصورة المتحركة للرمز، يمنحك تشغيل التطبيق خيار تخطي تسلسلاً في الحالات التي يكون فيها التطبيق جاهزًا في وقت سابق. يشغّل التطبيق "onResume()" أو تنتهي مهلة شاشة البداية تلقائيًا، لذا تأكد من إمكانية يتم تخطيها بارتياح. يجب إغلاق شاشة البداية باستخدام "onResume()" فقط. عندما يكون التطبيق ثابتًا من الناحية المرئية، لذلك لا يتم تضمين أدوات دوار إضافية احتاجت. يمكن أن يؤدي تقديم واجهة غير مكتملة إلى إرباك المستخدمين وربما تعطي انطباعًا بعدم القدرة على التنبؤ أو نقص الإتقان.

متطلبات الصور المتحركة لشاشة البداية

يجب أن تتوافق شاشة البداية مع المواصفات التالية:

  • ضبط لون خلفية نافذة واحدة بدون شفافية نهارًا وليلاً البيانات المتوافقة مع مكتبة متوافقة لـ SplashScreen

  • تأكّد من أنّ الرمز المتحرك يستوفي المواصفات التالية:

    • التنسيق: يجب أن يكون الرمز AnimatedVectorDrawable (AVD) XML.
    • الأبعاد: يجب أن يكون حجم رمز متوسّط مدة المشاهدة أربعة أضعاف حجم فيديو تكيُّفي. على النحو التالي:
      • يجب أن تكون منطقة الرمز 432 وحدة بكسل مستقلة الكثافة (dp)، أي أربعة أضعاف المنطقة 108 وحدة بكسل مستقلة الكثافة لرمز تكيُّفي غير مخفٍّ
      • يكون الثلثان الداخليان للصورة مرئيًا على أيقونة مشغّل التطبيقات، كما يجب أن تكون 288 وحدة بكسل مستقلة الكثافة - أي أربعة أضعاف 72 وحدة بكسل مستقلة الكثافة يشكل المنطقة الداخلية المقنَّعة للأيقونة التكيّفية.
    • المدة: ننصح بعدم تجاوز 1,000 ملي ثانية على الهواتف. يمكنك استخدام البداية المتأخرة، ولكن لا يمكن أن تكون أطول من 166 ملي ثانية. إذا كان التطبيق مدة بدء التشغيل أطول من 1000 ملي ثانية، فيمكنك تجربة استخدام رسوم متحركة متكررة.
  • اضبط وقتًا مناسبًا لإغلاق شاشة البداية، فيتم تطبيقك يرسم إطاره الأول. يمكنك تخصيص هذا النموذج كما هو موضّح في القسم المتعلق إبقاء شاشة البداية على الشاشة لفترات أطول

مراجع عن شاشات البداية

الشكل 5. مثال على متوسّط مدة المشاهدة

تنزيل مثال لمجموعة أدوات البدء، الذي يشرح كيفية إنشاء رسم متحرك وتنسيقه وتصديره إلى متوسّط مدة المشاهدة وتتضمّن ما يلي:

  • ملف مشروع Adobe After Effects للرسوم المتحركة.
  • ملف AVD XML النهائي الذي تم تصديره.
  • مثال على GIF للصورة المتحركة

من خلال تنزيل هذه الملفات، أنت توافق على بنود خدمة Google

توضّح سياسة خصوصية Google الطريقة التي البيانات التي تتم معالجتها في هذه الخدمة.

تخصيص شاشة البداية في تطبيقك

يستخدم SplashScreen تلقائيًا windowBackground للمظهر في حال windowBackground هو لون واحد. لتخصيص شاشة البداية، يمكنك إضافة السمات الخاصة بموضوع التطبيق.

يمكنك تخصيص شاشة البداية لتطبيقك من خلال تنفيذ أيّ من الإجراءات التالية:

  • يمكنك ضبط سمات المظهر لتغيير مظهره.

  • أبقِ الفيديو على الشاشة لفترة أطول.

  • خصِّص الصورة المتحركة لإغلاق شاشة البداية.

البدء

توفّر مكتبة SplashScreen الأساسية شاشة البداية في Android 12 للجميع أجهزة من واجهة برمجة التطبيقات 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 لاستبدال الأيقونة في منتصف نافذة البداية.

    بالنسبة إلى التطبيقات التي تستهدف الإصدار 12 من نظام التشغيل Android (المستوى 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 لتحديد ما إذا كان تطبيقك يعرض دائمًا الرمز على شاشة البداية الإصدار 13 من نظام التشغيل Android والإصدارات الأحدث القيمة الافتراضية هي 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;
}

مصادر إضافية