пятница, 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. Код работает как надо,но есть одно но.растягивает картинку.попробую покопаться.

    ОтветитьУдалить
    Ответы
    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. В итоге усе довольны :)

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