Заставки

Начиная с Android 12, API SplashScreen позволяет запускать приложения с анимацией, включая движение внутри приложения при запуске, экран-заставку со значком вашего приложения и переход к самому приложению. SplashScreen является Window и, следовательно, охватывает Activity .

Рисунок 1. Заставка.

Экран-заставка добавляет стандартные элементы дизайна при каждом запуске приложения, но его также можно настраивать, чтобы ваше приложение могло сохранять свой уникальный бренд.

Помимо использования API платформы SplashScreen , вы также можете использовать библиотеку совместимости SplashScreen , которая является оболочкой API SplashScreen .

Как работает заставка

Когда пользователь запускает приложение, когда процесс приложения не запущен ( холодный старт ) или Activity не создана ( теплый старт ), происходят следующие события:

  1. Система отображает заставку с использованием заданных вами тем и любой анимации.

  2. Когда приложение готово, экран-заставка закрывается и отображается приложение.

Заставка никогда не отображается при горячем запуске .

Элементы и механика заставки

Элементы заставки определяются XML-файлами ресурсов в файле манифеста Android. Для каждого элемента существуют светлые и темные версии режима.

Настраиваемые элементы заставки состоят из значка приложения, фона значка и фона окна:

Изображение, показывающее элементы, содержащиеся в заставке.
Рисунок 2. Настраиваемые элементы заставки.

Рассмотрим следующие элементы, показанные на рисунке 2:

1 Значок приложения должен быть векторным, который можно рисовать. Он может быть статическим или анимированным. Хотя анимация может иметь неограниченную продолжительность, мы рекомендуем не превышать 1000 миллисекунд. Значок запуска установлен по умолчанию.

2 Фон значка является необязательным и полезен, если вам нужен больший контраст между значком и фоном окна. Если вы используете адаптивную иконку , ее фон отображается, если он достаточно контрастен с фоном окна.

3 Как и в случае с адаптивными значками, одна треть переднего плана скрыта.

4 Фон окна состоит из одного непрозрачного цвета. Если фон окна установлен и имеет простой цвет, он используется по умолчанию, если атрибут не установлен.

Размеры заставки

Значок заставки использует те же характеристики, что и адаптивные значки , а именно:

  • Фирменное изображение: оно должно быть 200×80 dp.
  • Значок приложения с фоном значка: он должен иметь размер 240×240 dp и помещаться в круг диаметром 160 dp.
  • Значок приложения без фона значка: он должен иметь размер 288×288 dp и помещаться в круг диаметром 192 dp.

Например, если полный размер изображения составляет 300×300 dp, значок должен помещаться в круг диаметром 200 dp. Все, что находится за пределами круга, становится невидимым (маскируется).

Изображение, показывающее разные размеры значков для сплошного и прозрачного фона.
Рис. 3. Размеры значков заставки для сплошного и прозрачного фона соответственно.

Анимация заставки и последовательность запуска

Дополнительная задержка часто связана с запуском приложения при холодном старте. Добавление анимированного значка на заставку имеет очевидную эстетическую привлекательность и обеспечивает более высокий уровень обслуживания. Исследования пользователей показывают, что воспринимаемое время запуска сокращается при просмотре анимации.

Анимация экрана-заставки встроена в компоненты последовательности запуска, как показано на рис. 4.

Изображение, показывающее последовательность запуска в двенадцати последовательных кадрах, начиная с нажатия на значок запуска и заполняя экран по мере увеличения.
Рисунок 4. Последовательность запуска.
  1. Введите анимацию: она состоит из представления системы на заставке. Он контролируется системой и не настраивается.

  2. Экран-заставка (отображается во время части «ожидания» последовательности): экран-заставку можно настроить, что позволяет вам использовать собственную анимацию логотипа и фирменный стиль. Для правильной работы он должен соответствовать требованиям, описанным на этой странице.

  3. Анимация выхода: состоит из анимации, которая скрывает заставку. Если вы хотите настроить его , используйте SplashScreenView и его значок. Вы можете запустить на них любую анимацию с настройками трансформации, непрозрачности и цвета. В этом случае вручную удалите заставку после завершения анимации.

При запуске анимации значка запуск приложения дает вам возможность пропустить последовательность действий в тех случаях, когда приложение готово раньше. Приложение запускает onResume() или время ожидания заставки автоматически отключается, поэтому убедитесь, что движение можно легко пропустить. Экран-заставку можно закрыть с помощью onResume() только в том случае, если приложение стабильно с визуальной точки зрения, поэтому дополнительные счетчики не нужны. Представление неполного интерфейса может раздражать пользователей и создавать впечатление непредсказуемости или несовершенства.

Требования к анимации заставки

Ваш экран-заставка должен соответствовать следующим характеристикам:

  • Установите один цвет фона окна без прозрачности. Режим «День» и «Ночь» поддерживаются библиотекой совместимости SplashScreen .

  • Убедитесь, что анимированный значок соответствует следующим требованиям:

    • Формат: значок должен быть XML-файлом AnimatedVectorDrawable (AVD) .
    • Размеры: значок AVD должен быть в четыре раза больше адаптивного значка, а именно:
      • Площадь значка должна составлять 432 dp — другими словами, в четыре раза больше площади 108 dp у немаскированного адаптивного значка.
      • Внутренние две трети изображения видны на значке запуска, и их разрешение должно составлять 288 dp — другими словами, в четыре раза больше 72 dp, которые составляют внутреннюю замаскированную область адаптивного значка.
    • Продолжительность: на телефонах мы рекомендуем не превышать 1000 мс. Вы можете использовать отложенный старт, но он не может быть дольше 166 мс. Если время запуска приложения превышает 1000 мс, рассмотрите возможность использования зацикленной анимации.
  • Установите подходящее время для закрытия заставки, которая происходит, когда ваше приложение рисует свой первый кадр. Вы можете дополнительно настроить это, как описано в разделе о сохранении заставки на экране в течение длительного времени .

Ресурсы экрана-заставки

Рисунок 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"
}

Котлин

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 ), прослушиватель перед рисованием не требуется.

Котлин

// 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
                }
            }
        }
    )
}

Ява

// 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() .

Котлин

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

Ява

@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 чтобы узнать, когда началась анимация. Вы можете рассчитать оставшуюся продолжительность анимации значка следующим образом:

Котлин

// 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
}

Ява

// 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;
}

Дополнительные ресурсы