Делаем живые обои с gif анимации
Делаем живые обои с gif анимации
Главная » Делаем живые обои с gif анимации

В этом уроке мы научимся создавать живые обои для Android устройства, используя для этого обычную gif анимацию. Конечно, есть и другой способ создания живых обоев, с использованием собственных изображений, математических подсчетов и собственноручно созданной анимации, и его мы как нибудь тоже рассмотрим, но это занимает много сил, времени и требует от создателя творческого мышления, попробуй ка выдумай что нибудь толковое. Но мы пойдем намного более легким путем и сделаем собственные живые обои из обыкновенной gif анимации.

Начнем с того, что подготовим анимацию для наших живых обоев. Конечно, вы можете найти любую анимацию которая вам понравится и использовать ее, но если вам день это делать - качайте эту

Создаем новый проект, все названия файлов можете оставлять по умолчанию, можете вводить свои, как вам удобно. Минимальную версию Android выберем 2.2 Froyo, а при выборе activity выбираем Add No Activity и жмем финиш. 

Для живых обоев необходимо создать файл, который будет их описывать. Для этого создаем в нашем проекте папку xml:

Создаем папку 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.

Категория: Уроки программирования | Просмотров: 2144 | Добавил: Oleg | Теги: gif анимация, живые обои, Android программирование | Рейтинг: 3.0/2
Всего комментариев: 2
avatar
1
почему то в манифесте android:name=".GIFWallpaperService" выделен красным в чем причина кто знает по подсказкам смотрел проверте плагин IntelliLang проверел с ним все норм вклучен
avatar
2
Не работает
avatar