Створіть живі шпалери для Android, використовуючи GIF Анімацію
Ukrainian (українська мова) translation by Elen (you can also view the original English article)
Ви
коли-небудь бачили красиву 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 та замініть його вміст наступним:
1 |
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
<wallpaper
|
3 |
xmlns:android="http://schemas.android.com/apk/res/android" |
4 |
android:label="GIF Wallpaper" |
5 |
android:thumbnail="@drawable/ic_launcher"> |
6 |
</wallpaper>
|
Значення імені (label) та іконки (thumbnail) дуже важливі, оскільки вони будуть показуватися в списку в списке шпалер, доступних на вашому пристрої.
3. Редагуємо Маніфест
Щоб запустити живі шпалери, наш додаток потребує тільки один дозвіл - android.permission.BIND_WALLPAPER
.
Живі шпалери запускаються як об'єкт Service
, який може приймати значення android.service.wallpaper.WallpaperService
в якості екшена, запланованої дії. Назвемо Service
GIFWallpaperService - і додамо його в маніфест проекту - AndroidManifest.xml.
1 |
<service
|
2 |
android:name=".GIFWallpaperService" |
3 |
android:enabled="true" |
4 |
android:label="GIF Wallpaper" |
5 |
android:permission="android.permission.BIND_WALLPAPER" > |
6 |
<intent-filter>
|
7 |
<action android:name="android.service.wallpaper.WallpaperService"/> |
8 |
</intent-filter>
|
9 |
<meta-data
|
10 |
android:name="android.service.wallpaper" |
11 |
android:resource="@xml/wallpaper" > |
12 |
</meta-data>
|
13 |
</service>
|
Далі, щоб переконатися, що наш додаток може бути встановленим тільки на пристрої, які підтримують живі шпалери, ми додамо в маніфест такий код:
1 |
<uses-feature
|
2 |
android:name="android.software.live_wallpaper" |
3 |
android:required="true" > |
4 |
</uses-feature>
|
4. Додаємо GIF анімацію
Скопіюйте завантажену GIF анімацію з Flickr в папку проекта assets. Я назвав її girl.gif.
5. Створюємо сервис
Створимо новий Java клас та дамо йому назву - GIFWallpaperService.java. Він повинен наслідувати клас WallpaperService
.
1 |
public class GIFWallpaperService extends WallpaperService { |
2 |
|
3 |
}
|
Оскільки WallpaperService
– це абстрактний клас, ви повинні замістити метод onCreateEngine
і повернути приклад вашому Engine
, який може прорисовувати кадри для GIF.
Щоб використовувати GIF анімацію, вам потрібно спочатку конвертувати її в об'єкт Movie
. Для цього ви можете скористатись методом decodeStream
класу Movie
. Після того, як Movie
створено, відправте його в якості параметра в конструктор Engine
.
Ось як повинен виглядати метод onCreateEngine
:
1 |
@Override
|
2 |
public WallpaperService.Engine onCreateEngine() { |
3 |
try { |
4 |
Movie movie = Movie.decodeStream( |
5 |
getResources().getAssets().open("girl.gif")); |
6 |
|
7 |
return new GIFWallpaperEngine(movie); |
8 |
}catch(IOException e){ |
9 |
Log.d("GIF", "Could not load asset"); |
10 |
return null; |
11 |
}
|
12 |
}
|
6. Створіть Engine
Тепер розпочнемо роботу над Engine
. Створіть клас GIFWallpaperEngine всередині класу GIFWallpaperService
, який буде наслідувати WallpaperService.Engine
.
Додайте
наступні поля в цьому класі:
-
frameDuration
: ціле число, що вказує довжину затримки між перерисовкою анімації. Значення 20 дає нам 50 фреймі в секунду. -
visible
: логічна змінна, яка дає програмі зрозуміти, коли саме шпалери стають видимі на дисплеї. visible: логічна змінна, яка дає програмі зрозуміти, коли саме шпалери стають видимі на дисплеї. -
movie
: це анімаційний GIF в формі об'єкта Movie. -
holder
: це посилання на об'єктSurfaceHolder
, доступний пристрою Він буде ініційований за допомогою опису методаonCreate
. -
handler
: це об'єктHandler
, який буде використовуватися для запускуRunnable
, який відповідає за прорисовування шпалер.
Ваш клас повинен виглядати наступним чином:
1 |
private class GIFWallpaperEngine extends WallpaperService.Engine { |
2 |
private final int frameDuration = 20; |
3 |
|
4 |
private SurfaceHolder holder; |
5 |
private Movie movie; |
6 |
private boolean visible; |
7 |
private Handler handler; |
8 |
|
9 |
public GIFWallpaperEngine(Movie movie) { |
10 |
this.movie = movie; |
11 |
handler = new Handler(); |
12 |
}
|
13 |
|
14 |
@Override
|
15 |
public void onCreate(SurfaceHolder surfaceHolder) { |
16 |
super.onCreate(surfaceHolder); |
17 |
this.holder = surfaceHolder; |
18 |
}
|
19 |
}
|
Далі, створимо метод під назвою draw
, який буде прорисовувати вміст gif файла. Давайте розпишемо цей метод:
- Спочатку ми перевіряємо змінну
visible
на відповідність умовіtrue
. Якщо це так, ми продовжуємо. - Використовуємо команду
SurfaceHolder's
з методуlockCanvas
для створення полотна -Canvas
, на якому буде прорисовуватися наша анімація. - Рисуємо кадри GIF анімації
на
Canvas
, після масштабування та розміщення. - Після того, как рисування завершено передаємо
Canvas
назад вSurfaceHolder
. - Оновлюємо поточний кадр GIF анімації, використовуючи метод
setTime
об'єктаMovie
. - Знову викликаємо метод за допомогою
handler
після очікуванняframeDuration
в милісекундах.
Метод draw
ніколи не викликається безпосередньо. Він завжди викликається за допомогою використання об'єктів Handler
та Runnable
. Тому, давайте створимо об'єкт Runnable
та назвемо його drawGIF
.
Додайте в клас GIFWallpaperService
наступний код:
1 |
private Runnable drawGIF = new Runnable() { |
2 |
public void run() { |
3 |
draw(); |
4 |
}
|
5 |
};
|
6 |
|
7 |
private void draw() { |
8 |
if (visible) { |
9 |
Canvas canvas = holder.lockCanvas(); |
10 |
canvas.save(); |
11 |
// Adjust size and position so that
|
12 |
// the image looks good on your screen
|
13 |
canvas.scale(3f, 3f); |
14 |
movie.draw(canvas, -100, 0); |
15 |
canvas.restore(); |
16 |
holder.unlockCanvasAndPost(canvas); |
17 |
movie.setTime((int) (System.currentTimeMillis() % movie.duration())); |
18 |
|
19 |
handler.removeCallbacks(drawGIF); |
20 |
handler.postDelayed(drawGIF, frameDuration); |
21 |
}
|
22 |
}
|
Метод onVisibilityChanged
викликається автоматично, кожного разу, коли змінюється стан шпалер. Ми повинні переписати його, щоб на основі значення аргумента visible
, запускати або зупиняти drawGIF
. Метод removeCallbacks
об'єкта Handler
буде використовуватися, щоб зупинити завантажені шпалери drawGIF
.
1 |
@Override
|
2 |
public void onVisibilityChanged(boolean visible) { |
3 |
this.visible = visible; |
4 |
if (visible) { |
5 |
handler.post(drawGIF); |
6 |
} else { |
7 |
handler.removeCallbacks(drawGIF); |
8 |
}
|
9 |
}
|
І на кінець, перепишемо метод onDestroy
для Engine
, який буде зупиняти запуск drawGIF
, якщо шпалери деактивовані.
1 |
@Override
|
2 |
public void onDestroy() { |
3 |
super.onDestroy(); |
4 |
handler.removeCallbacks(drawGIF); |
5 |
}
|
7. Компілюйте та встановіть.
Теперь ваші живі шпалери готові. Зкомпілюйте їх та встановіть на ваш пристрій під Android. Після встановлення, ви зможете знайти їх в списку доступних шпалер.
Більшість лоунчерів дають вам можливість змінювати шпалери після тривалого доторку до екрану. Або ж ви можете зайти в меню налаштування дисплея, щоб змінити шпалери.



Якщо GIF виглядає надто маленьким, або не правильно розміщений, знову поверніться до методу draw
і налаштуйте масштаб та розміщення.
Висновок
Тепер ви знаєте, як використовувати GIF анімацію, щоб створити живі шпалери. Обовязково поекспериментуйте з іншими варіантами GIF анімації. Якщо ви захочете розмістити ваші шпалери на Google Play, переконайтесь, що у вас є дозвіл автора на використання анімації в комерційних цілях. Зайдіть на сайт Android Developer, щоб дізнатися більше про клас WallpaperService
.