Сделайте Живые Обои под Android Используя GIF Анимацию...
Вы когда нибудь видели красивую GIF анимацию, которая повторяется беспрерывно, и хотели бы поставить такую в качестве живых обоев на ваше устройство, которое работает под Android? Что ж, вы можете это сделать, и в этом уроке, я покажу вам как.
Введение
Чтобы создавать интересные и красивый живые обои с нуля, используя только математику и код, который будет генерировать анимацию, возможно придется много и долго потрудиться. А так же нужно привлечь всю свою креативность. С другой стороны, создать анимированные GIF обои, или найти такие в сети - гораздо проще. В этом уроке, вы узнаете, как конвертировать любоую GIF анимацию в живые обои.
Необходимая первоначальная подготовка
Убедитесь, что у вас установлена последняя версия Android Studio. Вы можете закачать ее с сайта Android Developer.
Хотя можно сделать любую GIF анимацию, я рекомендую вам загрузить хороший синемаграф. Синемаграф - это не что иное, как GIF анимация, которая обычно делается из видео, и плавно зацикливается. Вы можете найти много вариантов на Flickr.
В этом уроке, я использую синемаграф, созданный пользователем Flickr - djandyw.com, так как он распространяется по лицензии Creative Commons.
1. Создайте Новый Проект
Запустите Android Studio, создайте новый проект, и дайте ему название GIFWallpaper. Дайте ему уникальное имя, если вы планируете разместить его на Google Play.
Задайте для minimum SDK - API 8: Android 2.2 (Froyo).
Нашему приложению не нужен статус Activity
, поэтому выбираем Add No Activity и жмем Finish.
2. Описание Обоев
Для живых обоев, нужен файл, который будет их описывать. Создайте новый XML файл res/xml/wallpaper.xml и замените его содержание следующим:
<?xml version="1.0" encoding="UTF-8"?><wallpaper xmlns:android="http://schemas.android.com/apk/res/android" android:label="GIF Wallpaper" android:thumbnail="@drawable/ic_launcher"></wallpaper>
Значения имени (label) и иконки (thumbnail) важны, так как они будут показываться в списке обоев доступных на вашем устройстве.
3. Редактируем Манифест
Для запуска живых обоев, нашему приложению необходимо прописать одно разрешение - android.permission.BIND_WALLPAPER
.
Живые обои запускаются как объект Service
, который может принимать значение android.service.wallpaper.WallpaperService
в качестве intent action. Назовем Service
GIFWallpaperService - и добавим его в манифест проекта - AndroidManifest.xml.
<service android:name=".GIFWallpaperService" android:enabled="true" android:label="GIF Wallpaper" android:permission="android.permission.BIND_WALLPAPER" > <intent-filter> <action android:name="android.service.wallpaper.WallpaperService"/> </intent-filter> <meta-data android:name="android.service.wallpaper" android:resource="@xml/wallpaper" > </meta-data></service>
Далее, чтобы быть уверенным, что наше приложение ставится на устройство,которое может работать с живыми обоями, мы добавим в манифест такой код:
<uses-feature android:name="android.software.live_wallpaper" android:required="true" ></uses-feature>
4. Добавляем GIF анимацию
Копируйте загруженную с Flickr GIF анимацию в папку проекта - assets. Я дал ему название girl.gif.
5. Создаем Сервис
Создадим новый Java класс и назовем его GIFWallpaperService.java. Он должен наследовать класс WallpaperService
.
public class GIFWallpaperService extends WallpaperService { }
Поскольку WallpaperService
- это абстрактный класс, вы должны переопределить метод onCreateEngine
и вернуть экземпляр вашему Engine
, который может отрисовать кадры для GIF.
Чтобы использовать анимированный GIF, вы должны сперва конвертировать его в объект Movie
. Для этого вы можете использовать метод decodeStream
класса Movie
. После того как Movie
создан, отправьте его как параметр в конструктор Engine
.
Вот как должен выглядеть метод onCreateEngine
:
@Overridepublic WallpaperService.Engine onCreateEngine() { try { Movie movie = Movie.decodeStream( getResources().getAssets().open("girl.gif"));return new GIFWallpaperEngine(movie);}catch(IOException e){Log.d("GIF", "Could not load asset");return null;}}
6. Создаем Engine
Теперь давайте работать над Engine
. Создайте класс GIFWallpaperEngine внутри класса GIFWallpaperService
, который будет наследовать WallpaperService.Engine
.
В этом классе добавим следующие поля:
-
frameDuration
: целое число, указывающее длину задержки между перерисовкой анимации. Значение 20, дает нам 50 фреймов в секунду. -
visible
: логическая переменная, которая дает программе знать, когда именно обои видны на дисплее. Это важно, потому что нам не нужно отрисовывать обои, когда их не видно. -
movie
: это анимированный GIFв форме объектаMovie
. -
holder
: это отсылка к объектуSurfaceHolder
доступному в программе. Он будет инициирован с помощью описания методаonCreate
. -
handler
: это объектHandler
, который будет использоваться для запускаRunnable
, который отвечает за отрисовку обоев.
Ваш класс должен выглядеть таким образом:
private class GIFWallpaperEngine extends WallpaperService.Engine { private final int frameDuration = 20; private SurfaceHolder holder; private Movie movie; private boolean visible; private Handler handler; public GIFWallpaperEngine(Movie movie) { this.movie = movie; handler = new Handler(); } @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); this.holder = surfaceHolder; }}
Теперь создадим метод под названием draw
, который будет отрисовывать содержимое gif файла. Давайте распишем этот метод:
- Сначала мы проверяем переменную
visible
на условиеtrue
. Если это так, то мы продолжаем. - Используем комманду
SurfaceHolder"s
из методаlockCanvas
для создания холста -Canvas
, на котором будет отрисовываться наша анимация. - Рисуем кадра GIF анимации на
Canvas
, после масштабирования и позиционирования. - После того, как отрисовка завершена, передаем
Canvas
назад вSurfaceHolder
. - Обновляем текущий кадр GIF анимации, используя метод
setTime
объектаMovie
. - Вызываем метод снова используя
handler
после ожиданияframeDuration
в миллисекундах.
Метод draw
никогда не будет вызываться непосредственно. Он всегда вызывается через использование объектов Handler
и Runnable
. Поэтому, двайте создадим объект Runnable
и назавем его drawGIF
.
Добавьте в класс GIFWallpaperService
следующий код:
private Runnable drawGIF = new Runnable() { public void run() { draw(); }};private void draw() { if (visible) { Canvas canvas = holder.lockCanvas(); canvas.save(); // Adjust size and position so that // the image looks good on your screen canvas.scale(3f, 3f); movie.draw(canvas, -100, 0); canvas.restore(); holder.unlockCanvasAndPost(canvas); movie.setTime((int) (System.currentTimeMillis() % movie.duration())); handler.removeCallbacks(drawGIF); handler.postDelayed(drawGIF, frameDuration); }}
Метод onVisibilityChanged
автоматически вызывается, каждый раз когда будет меняться состояние обоев. Мы должны переписать его, что бы на основе значения аргумента visible
, запускать или останавливать drawGIF
. Метод removeCallbacks
объекта Handler
будет использоваться для остановки запущенных обоев drawGIF
.
@Overridepublic void onVisibilityChanged(boolean visible) { this.visible = visible; if (visible) { handler.post(drawGIF); } else { handler.removeCallbacks(drawGIF); }}
И наконец, пререпишем метод onDestroy
для Engine
, который будет останавливать запуск drawGIF
, если обои деактивированы.
@Overridepublic void onDestroy() { super.onDestroy(); handler.removeCallbacks(drawGIF);}
7. Скомпилируйте и Установите
Теперь ваши живые обои готовы. Скомпилируйте их и установите на ваш девайс под Android. После того, как вы их установите, вы сможете найти их в списке доступных обоев.
Большинство лаунчеров дают вам возможность изменять обои, после долгого нажатия на экран. Или вы можете зайти в настройки экрана, чтобы сменить обои.
Если GIF выглядить слишком маленьким, или неправильно позиционирован, вернитесь вновь к методу draw
и настройте масштаб и положение.
Заключение
Тепере вы знаете, как использовать GIF анимацию, чтобы создать живые обои. Обязательно поэкспериментируюйте с другими вариантами GIF анимации. Если вы захотите выложить свои обои на Google Play, убедитесь, что у вас есть разрешение, от автора, на использование его GIF анимации в коммерческих целях. Зайдите на сайт Android Developer, чтобы узнать больше о классе WallpaperService
.