Главная » Делаем живые обои с gif анимации | |
В этом уроке мы научимся создавать живые обои для Android устройства, используя для этого обычную gif анимацию. Конечно, есть и другой способ создания живых обоев, с использованием собственных изображений, математических подсчетов и собственноручно созданной анимации, и его мы как нибудь тоже рассмотрим, но это занимает много сил, времени и требует от создателя творческого мышления, попробуй ка выдумай что нибудь толковое. Но мы пойдем намного более легким путем и сделаем собственные живые обои из обыкновенной gif анимации. Начнем с того, что подготовим анимацию для наших живых обоев. Конечно, вы можете найти любую анимацию которая вам понравится и использовать ее, но если вам день это делать - качайте эту. Создаем новый проект, все названия файлов можете оставлять по умолчанию, можете вводить свои, как вам удобно. Минимальную версию Android выберем 2.2 Froyo, а при выборе activity выбираем Add No Activity и жмем финиш. Для живых обоев необходимо создать файл, который будет их описывать. Для этого создаем в нашем проекте папку 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) обоев будут важны при выборе их в списке доступных на устройстве обоев. Для запуска живых обоев нашему приложению понадобится получить одно разрешение в файле манифеста AndroidManifest.xml:
android.permission.BIND_WALLPAPER
Живые обои запускаются как объект Service, который может принимать значение android.service.wallpaper.WallpaperService. Назовем сервис GIFWallpaperService и добавим его в манифест проекта:
<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>
Здесь возможны ругательства от Android Studio, но мы молча идем дальше. Теперь нам нужно позаботиться о том, чтобы наше приложение обоев могло быть установлено только на то устройство, которое их поддерживает. Для этого добавим в манифест еще вот такой код:
<uses-feature
android:name="android.software.live_wallpaper"
android:required="true" >
</uses-feature>
Теперь добавим в проект файл анимации. Для этого нужно создать специальную папку под названием assets и поместить туда нашу анимацию по имени priroda.gif. Папка assets должна находиться на одном уровне с папкой res. Создаем новый java класс и назовем его GIFWallpaperService.java. Он должен наследовать класс WallpaperService:
public class GIFWallpaperService extends WallpaperService {
}
Android Studio потребует с нас описать необходимый для этого класса метод под названием onCreateEngin. Безропотно соглашаемся и добавляем следующий код:
@Override
public WallpaperService.Engine onCreateEngine() {
try {
Movie movie = Movie.decodeStream(
getResources().getAssets().open("priroda.gif"));
return new GIFWallpaperEngine(movie);
}catch(IOException e){
Log.d("GIF", "Невозможно загрузить");
return null;
}
}
Теперь внутри файла GIFWallpaperService.java создадим класс по имени GIFWallpaperEngine, который будет наследовать WallpaperService.Engine. В этот класс мы добавим следующее: - frameDuration - целое число, указывающие длину задержки между перерисовкой анимации. Значение 20 дает нам 50 фреймов в секунду; - visible - эта логическая переменная дает программе знать, когда именно обои видны на дисплее. Когда обои не будут видимыми, то и перерисовку выполнять ни к чему; - movie - это анимированный gif файл в форме объекта movie; - holder - это отсылка к объекту SurfaceHolder, он будет инициализирован с помощью описания соответствующего метода в onCreate (); - handler - Это объект Handler, который будет использоваться для запуска анимации. На данный момент наш класс должен выглядеть примерно так:
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, то работа метода идет дальше; - используем команду lockCanvas из метода SurfaceHolder, для создания холста для вырисовывания нашей анимации; - после масштабирования и расположения анимации, вырисовываем ее на холсте Canvas; - когда вырисовывание закончено, передаем Canvas обратно в SurfaceHolder; - обновляем текущее состояние анимации с помощью метода setTime; - вызываем вышеуказанный метод снова после того, как пройдет время frameDuration с помощью hanler. Метод draw никогда не будет вызываться непосредственно. Он будет вызываться через использование объектов Handler и Runnable. Следовательно, нужно создать объект Runnable, назовем его drawGIF. Чтобы реализовать все сказанное, добавим в GIFWallpaperService.java следующий код:
private Runnable drawGIF = new Runnable() {
public void run() {
draw();
}
};
private void draw() {
if (visible) {
Canvas canvas = holder.lockCanvas();
canvas.save();
//Регулируем масштаб и положение на экране нашей анимации
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:
@Override
public void onVisibilityChanged(boolean visible) {
this.visible = visible;
if (visible) {
handler.post(drawGIF);
} else {
handler.removeCallbacks(drawGIF);
}
}
Ну и напоследок, пропишем для нашего класса GIFWallpaperService.java метод onDestroy, который будет полностью останавливать все процессы
@Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(drawGIF);
}
На этом все шаги по созданию живых обоев с использованием для них gif анимации закончены. Компилируем проект, устанавливаем приложение на эмулятор устройство, устанавливаем в настройках обоев наше творение и любуемся прекрасным результатом: На случай, если у вас что то не заработало, здесь показано, как должны выглядеть код AndroidManifest.xml и GIFWallpaperService.java. | |
|
Всего комментариев: 2 | |
| |