пятница, 7 марта 2014 г.

Добавляем Splash Screen в приложение для Android

Splash Screen используется для того чтобы не видеть черный экран при запуске приложения. Ниже вы узнаете, как легко создать такую «заставку». Примечание: это один из возможных вариантов создания Splash Screen. За тему для этой заметки благодарю Балашова Валерия.

Upd (07.03.14). Дополнение из комментариев.
Update (17.03.14). Дополнение по выравниванию картинки
Update (18.03.14 0:35). Изменяем цвет фона под прозрачной картинкой
Update (25.11.14). В XE7 встроена возможность добавления заставки. Читайте справку и мою статью Как добавить "резиновый" SplashScreen в XE7

Начнём.
Что нужно сделать:
  1. Создать картинку (splash.png), которую задеплоим в папку «res\drawable\»
  2. Создать файл стиля (style.xml), который задеплоим в папку «res\values\»
  3. Внести маленькое изменение в файл «AndroidManifest.template.xml»
Создание файлов.
Создаём картинку в Photoshop’е или в любом удобном для вас редакторе. Для примера, я сделал картинку «Powered by Delphi XE5» с разрешением 768x1024.

Создаём файл стиля в любом текстовом редакторе (я использую Notepad++) и вписываем туда:
<resources>
<style name="MyTheme.NoTitleBar.CustomBackground" parent="@android:Theme.Holo">
  <item name="android:windowBackground">@drawable/splash</item>
  <item name="android:windowNoTitle">true</item>
  <item name="android:windowFullscreen">true</item>
</style>
</resources>

Теперь необходимо задеплоить эти файлы в проект:

Жмём «Ctrl + F9» для компиляции проекта и создания файла «AndroidManifest.template.xml».

Вносим изменение в файл «AndroidManifest.template.xml».
Открываем файл «AndroidManifest.template.xml» и ищем строчку «android:theme="%theme%"» и заменяем её на строчку «android: theme = "@style/MyTheme.NoTitleBar.CustomBackground"». Сохраняем файл.

Теперь компилируем и запускаем приложение на устройстве (эмуляторе), смотрим результат.

Исходный код: Скачать с Google Drive

Update (07.03.14). Запрещаем растягивать картинку.
Делается все по инструкции, но создается еще один файл "splash_centered.xml". Деплоится так же в "res\drawable\".
Его содержимое:
<bitmap xmlns:android="http://schemas.android.com/apk/res/android"
    android:src="@drawable/splash"
    android:gravity="center"/>


После этого в файле "style.xml" строку

<item name="android:windowBackground">@drawable/splash</item>

меняем на

<item name="android:windowBackground">@drawable/splash_centered</item>

все, теперь изображение по центру и имеет оригинальные размеры.

Update (17.03.14). Дополнение, к предыдущему обновлению.
Для того чтобы управлять положением и размерами картинки нужно использовать атрибут «android:gravity». Можно указывать несколько значений для этого атрибута, для этого используйте вертикальную черту «|». Значения, которые можно указывать в этом атрибуте: http://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html#attr_android:gravity
Для примера, я выставляю вместо этого значения «android:gravity="center"» (отображаем по центру и с оригинальными размерами) вот это «android:gravity="fill"» и картинка начинает подстраиваться под размеры дисплея.

Update (18.03.14 0:35). Изменяем цвет фона под прозрачной картинкой
Как добавить другой цвет фона и прозрачную картинку. Способ работает на моём устройстве, но я не проверял на соответствие правилам Гугла.
Пример:
Не обращайте внимания на надпись и цвета, это всё сделано на скорую руку, для примера.
Картинка на видео - это надпись размеры 320x160, фон прозрачный.

Что необходимо:
Если вы выполнили предыдущие Update’ы и вам необходимо сменить цвет фона, т.к. через прозрачную картинку видно чёрный фон, то читаем дальше.

Сейчас у вас имеется 3 файла, которые вы задеплоили:
style.xml - res\values\
splash.png - res\drawable\
splash_centered.xml - res\drawable\

Чтобы изменить фон за картинкой, нам необходим ещё один файл:
color.xml – деплоим в res\values\
внутри пишем(например):
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="blue">#ff324adb</color>
</resources>

Описание:
«blue» - имя цвета, к нему будем обращаться из style.xml
«#ff324adb» - ff – это уровень прозрачности в шестнадцатеричной системе исчисления(макс. 255 = ff = не прозрачно); «324adb» - это цвет

Далее вносим изменения в файл style.xml:
Добавляем новую строчку: "android:background" и изменяем старую "android:windowBackground"
<resources>
<style name="MyTheme.NoTitleBar.CustomBackground" parent="@android:Theme.Holo">
  <item name="android:background">@drawable/splash_centered</item>
  <item name="android:windowBackground">@color/blue</item>
  <item name="android:windowNoTitle">true</item>
  <item name="android:windowFullscreen">true</item>
</style>
</resources>




Данная статья основана на корейской (안드로이드 테마를 이용한 Splash Window 구현) и китайской (http://www.cnblogs.com/ChinaEHR/p/3368299.html) статьях.

26 комментариев:

  1. Код работает как надо,но есть одно но.растягивает картинку.попробую покопаться.

    ОтветитьУдалить
  2. Здравствуйте, Валерий. Спасибо за кучу полезной информации(особенно при тотальной нехватке информации по FM).
    Вопрос: Я кидаю на сплешскрин PNG с прозрачностью, фон подложки при запуске оказывается черным. Как его поменять на белый? Спасибо!

    ОтветитьУдалить
    Ответы
    1. Спасибо Роман.Но благодарности в первую очередь заслуживает создатель данного блога)).Я лишь предложил тему.
      По поводу белого фона.К сожалению сейчас нет возможности протестировать,но думаю должно помочь.Добавьте в файл splash_centered.xml строку
      android:background="#ffffff"
      Я думаю этого достаточно.

      Удалить
    2. Лично у меня не получилось поменять цвет фона таким способом.

      Удалить
    3. Тоже не получилось. Плюсом картинка на сплеше явно пережатая(по сравнению с задеплоеным исходником), видно корявое сжатие или интерполяция Г.

      Удалить
    4. Для того чтобы управлять положением и размерами картинки нужно использовать атрибут «android:gravity». Можно указывать несколько значений для этого атрибута, для этого используйте вертикальную черту «|». Значения, которые можно указывать в этом атрибуте: http://developer.android.com/reference/android/graphics/drawable/BitmapDrawable.html#attr_android:gravity
      Для примера я выставляю вместо этого значения «android:gravity="center"» (отображаем по центру и с оригинальными размерами) вот это «android:gravity="fill"» и картинка начинает подстраиваться под размеры дисплея.
      Попробуйте поиграть с этим атрибутов.

      Удалить
    5. Добавил информацию про управление размерами, положением, фоном.

      Удалить
    6. Снял скриншоты сплеша. При gravity=center изображение увеличено по разрешению ровно в 2 раза! Top, left, bottom, right - тоже самое.
      Возможно какие-то траблы связанные с плотностью пикселей дисплея.
      Изображение выглядит ужасно - растянуто в 2 раза, глазу неприятно.

      https://lh6.googleusercontent.com/-HdtsG8W9PC0/UyhlZUOumxI/AAAAAAAABXg/SbeYrsin2Xo/w794-h706-no/Screenshot_2014-03-18-20-50-21.jpg

      Удалить
    7. Собственно я идиот. Изображения для всех плотностей пикселей раскидываем по папкам res/ldpi и т.д.

      Удалить
  3. Этот комментарий был удален автором.

    ОтветитьУдалить
  4. Извини, а мне пишет
    No resource found that matches the given name (at 'theme' with value '@style/MyTheme.NoTitleBar.CustomBackground').

    ОтветитьУдалить
    Ответы
    1. Честно говоря, не знаю, откуда у вас взялась такая ошибка. Проект скачал и проверил, потом внёс изменения, чтобы картинка не растягивалась, проверил, всё работает без ошибок.

      Удалить
    2. Файл стиля задеплоили правильно?жалуется на отсутствие ресурса.style.xml назван правильно?

      Удалить
    3. Такая же ошибка. Файлы style.xml и splash.png при этом добросовестно пропадают. Delphi XE7

      Удалить
    4. В XE7 этот процесс максимально упрощён, почитайте официальную справку и мою статью http://delphifmandroid.blogspot.ru/2014/10/splashscreen-xe7.html

      Удалить
  5. Гм. Работает. Но....
    У меня появляется splash. Держится 1-2 секунды. Потом 3-4 секунды - черный экран. И только потом - окно приложения.
    Т.е. смысл splash-а весьма сомнителен. Я думал он будет на экране до тех пор, пока не проявится окно приложения. Или я что то не так делаю?

    ОтветитьУдалить
  6. Где эти папки создавать и какой манифест редактировать?

    ОтветитьУдалить
  7. Здравствуйте Андрей.
    Код замечательно работает. Показывается сплеш с моей png с прозрачностью, фон отображается как надо.
    НО! Теперь эта фоновая png отображается на ВСЕХ бекграундах всех элементов, которые рождены, как я понимаю, от TControl (TListBox, TCombobox и т.д.)
    Подскажите пожалуйста, как можно сделать так, чтобы png отображалась только на сплеше.

    ОтветитьУдалить
    Ответы
    1. присоединяюсь к вопросу. Также фоновая картинка вылезает на Showmessage

      Удалить
  8. файл res/drawable/splash.png
    можно использовать в программе после запуска и как к нему обратиться?

    ОтветитьУдалить
  9. 3 раза пробовал.. Где-то косячу чтоль, не могу понять. При F9 ошибка вылетает:

    [PAClient Error] Error: E2312 D:\---ПУТЬ---\AndroidManifest.xml:17: error: Error: String types not allowed (at 'theme' with value '%@style/MyTheme.NoTitleBar.CustomBackground%').
    Все делаю по пунктам скрупулезно до Update (07.03.14).
    Делаю, правда, в ХЕ6, язык с++. Есть мысли где собака?

    ОтветитьУдалить
    Ответы
    1. Проблема всему - кривые клешни. Все работает. Автору непоколебимый респект!

      Удалить
  10. Спасибо! Отличная статья! На LG L90 всё работает

    ОтветитьУдалить
  11. Супер статья.
    В моём случае, клиент попросил чтобы title bar оставался видимым постоянно (дабы смотреть заряд батареи, статус интернета и т.д.). Лениво ему было скрольнуть пальчиком. Решилось удалением строки "item name="android:windowFullscreen" true /item" из файла style.xml. В итоге усе довольны :)

    ОтветитьУдалить