Как сделать живые обои android studio
В этом уроке мы научимся создавать живые обои для Android устройства, используя для этого обычную gif анимацию. Конечно, есть и другой способ создания живых обоев, с использованием собственных изображений, математических подсчетов и собственноручно созданной анимации, и его мы как нибудь тоже рассмотрим, но это занимает много сил, времени и требует от создателя творческого мышления, попробуй ка выдумай что нибудь толковое. Но мы пойдем намного более легким путем и сделаем собственные живые обои из обыкновенной gif анимации.
Начнем с того, что подготовим анимацию для наших живых обоев. Конечно, вы можете найти любую анимацию которая вам понравится и использовать ее, но если вам день это делать — качайте эту.
Создаем новый проект, все названия файлов можете оставлять по умолчанию, можете вводить свои, как вам удобно. Минимальную версию Android выберем 2.2 Froyo, а при выборе activity выбираем Add No Activity и жмем финиш.
Для живых обоев необходимо создать файл, который будет их описывать. Для этого создаем в нашем проекте папку xml:
В ней файл по имени wallpaper.xml и добавляем туда следующий код:
Введенные здесь значения имени (label) и иконки (thumbnail) обоев будут важны при выборе их в списке доступных на устройстве обоев.
Для запуска живых обоев нашему приложению понадобится получить одно разрешение в файле манифеста AndroidManifest.xml:
Живые обои запускаются как объект Service, который может принимать значение android.service.wallpaper.WallpaperService. Назовем сервис GIFWallpaperService и добавим его в манифест проекта:
Здесь возможны ругательства от Android Studio, но мы молча идем дальше. Теперь нам нужно позаботиться о том, чтобы наше приложение обоев могло быть установлено только на то устройство, которое их поддерживает. Для этого добавим в манифест еще вот такой код:
Теперь добавим в проект файл анимации. Для этого нужно создать специальную папку под названием assets и поместить туда нашу анимацию по имени priroda.gif. Папка assets должна находиться на одном уровне с папкой res.
Создаем новый java класс и назовем его GIFWallpaperService.java. Он должен наследовать класс WallpaperService:
Android Studio потребует с нас описать необходимый для этого класса метод под названием onCreateEngin. Безропотно соглашаемся и добавляем следующий код:
Теперь внутри файла GIFWallpaperService.java создадим класс по имени GIFWallpaperEngine, который будет наследовать WallpaperService.Engine. В этот класс мы добавим следующее:
— frameDuration — целое число, указывающие длину задержки между перерисовкой анимации . Значение 20 дает нам 50 фреймов в секунду;
— visible — эта логическая переменная дает программе знать, когда именно обои видны на дисплее. Когда обои не будут видимыми, то и перерисовку выполнять ни к чему ;
— movie — это анимированный gif файл в форме объекта movie ;
— holder — это отсылка к объекту SurfaceHolder, он будет инициализирован с помощью описания соответствующего метода в onCreate () ;
— handler — Это объект Handler, который будет использоваться для запуска анимации.
На данный момент наш класс должен выглядеть примерно так:
Далее создаем метод draw, он будет вырисовывать содержимое gif файла. Ознакомимся с ним получше:
— сначала мы выполняем проверку переменной visible , если она имеет значение true, то работа метода идет дальше;
— используем команду lockCanvas из метода SurfaceHolder, для создания холста для вырисовывания нашей анимации ;
— после масштабирования и расположения анимации, вырисовываем ее на холсте Canvas ;
— когда вырисовывание закончено, передаем Canvas обратно в SurfaceHolder ;
— обновляем текущее состояние анимации с помощью метода setTime;
— вызываем вышеуказанный метод снова после того, как пройдет время frameDuration с помощью hanler.
Метод draw никогда не будет вызываться непосредственно. Он будет вызываться через использование объектов Handler и Runnable. Следовательно, нужно создать объект Runnable , назовем его drawGIF.
Чтобы реализовать все сказанное, добавим в GIFWallpaperService.java следующий код:
Когда состояние видимости живых обоев будет изменяться, автоматически будет вызываться метод onVisibilityChanged, сейчас мы его создадим и используя аргумент переменой visible, будем запускать или останавливать drawGIF. Для приостановки действия обоев будем использовать метод removeCallbacks:
Ну и напоследок, пропишем для нашего класса GIFWallpaperService.java метод onDestroy, который будет полностью останавливать все процессы в смартфоне, которые связаны с использованием сотворенных живых обоев:
На этом все шаги по созданию живых обоев с использованием для них gif анимации закончены. Компилируем проект, устанавливаем приложение на эмулятор устройство, устанавливаем в настройках обоев наше творение и любуемся прекрасным результатом:
Источник
Пишем Live Wallpapers (живые обои) для Android
Начиная с версии 2.1 в устройствах на базе системы Android появилась возможность использования Live Wallpapers (живых обоев). Это позволяет установить в качестве фона рабочего стола не только статичную картинку, но и произвольную программу создающую любое динамичное изображение или даже игру. Написанию простейшей заставки и посвящена эта статья. Предполагается, что у читателя уже установлена среда Eclipse и Android SDK и что он как минимум умеет импортировать и запускать готовые примеры, доступные для скачивания изархива.
Для начала создадим новый проект, с параметрами указанными на рисунке ниже:
После нажатия кнопки Finish мы получим стандартный шаблон проекта с одной созданной формой Activity. Так как Live Wallpapers появились только в 7 версии SDK, мы указали минимально допустимую версию системы, на которой программа может запуститься. Шаблон можно протестировать, запустив результат в эмуляторе и убедившись что надпись на форме выводится успешно ;).
Перейдем к написанию заставки. Для этого нам понадобится создать новый класс, унаследованный от WallpaperService. Назовем его StarFieldsShow, внутри класса необходимо реализовать метод onCreateEngine() и класс StarFieldsEngine, наследующий Engine. Именно внутри StarFieldsEngine проводится вся работа по рисованию заставки. Большая часть класса — это необходимая оболочка для взаимодействия заставки с системой, здесь обрабатываются действия запуска и остановки анимации, менеджмент ресурсов и определение видимости. Для нас интересными являются всего несколько основных методов. При смене размера экрана или его повороте вызывается метод onSurfaceChanged, внутри которого доступны параметры текущего экрана. Размер экрана сохраняется в глобальных переменных screen_width, screen_height класса StarFieldsEngine и служат для последующих расчетов динамичной графики, в этом методе мы выполняем инициализацию данных связанных с размером экрана.
Рисование кадра выполняется методом drawFrame(), который является оболочкой для метода рисования drawScreen(c) и реализует задержку между кадрами. Все действия по рисованию на Canvas выполняет метод drawScreen(c), в который передается контекст рисования, полученный через holder.lockCanvas(). Частота вывода кадров задается в mHandler.postDelayed в миллисекундах, по возможности устройство будет пытаться выводить кадры с заданной частотой. В примере принята скорость 30 кадров в секунду для большей плавности.
Реализовав класс StarFieldsShow, мы получили шаблон для заставки, но система пока не подозревает о ее существовании. Теперь необходимо добавить описание нового сервиса в AndroidManifest.xml. Проще всего это сделать открыв AndroidManifest.xml и добавив туда следующий текст:
Атрибут android:name должен иметь значение, совпадающее с именем класса, реализующего заставку, а android:permission разрешает устанавливать класс как заставку. Кроме корректировки манифеста, в ресурсах проекта необходимо создать папку xml, внутри которой создаем файл star_fields.xml, в будущем он нам понадобится для возможности настройки заставки пользователем. В ресурсы строк добавляем строку wallp_name с именем обоев в общем списке.
Запустив проект мы не обнаружим видимых изменений в отображаемой форме но, зайдя в настройки экрана и выбрав список Live Wallpapers, мы обнаружим там обои с именем Star Fields. Цель достигнута — перед нами готовый шаблон для написания живых обоев. (Сегодня совсем не проблема найти графику для создания живых обоев. Есть Яндекс Картинки, есть куча сайтов, которые предлагаютбесплатные обои.) Вархиве этот вариант находится в папке Template. Не смотря на то, что шаблон работает — он ничего не рисует на экране. Добавим функциональности.
В качестве эффекта реализуем простейшее движущееся звездное небо. Для этого нам понадобится структура данных о каждой точке — координата на экране и скорость по двум осям. Напишем класс StarItem, который будет не только содержать все необходимые данные, но и реализует два метода — вывод точки на экран и обработка ее перемещения. Приводить исходный текст не буду из-за его банальности, смотрим его текст вархиве. Теперь осталось добавить в основной класс создание массива таких точек, заполнение его координатами и вывод на экран. Добавим в класс StarFieldsEngine две статические переменные с параметрами заставки
и напишем метод initStars(), инициализирующий массив точек со случайными координатами и скоростью от 0 до SPEED_MAX пикселей за кадр по оси y. Это даст эффект перемещения влево с иллюзией глубины, как в демо конца 80-х годов прошлого века 😉
Осталось добавить инициализацию внутрь метода onSurfaceChanged, что позволит нам пересоздавать корректный набор данных в случае поворота экрана и добавить вывод на экран. Для этого переписываем метод drawScreen(Canvas c), вписав в его начало заливку экрана черным цветом, а потом вывод всех точек в цикле. В этом же цикле будем обрабатывать перемещение методом Move(), параметром которого служит размер экрана. Сохранять и восстанавливать контекст экрана парой методов c.save() — c.restore(), в принципе не обязательно для нашей задачи, но может пригодиться для заставок трансформирующих контекст.
Запустив проект, зайдя в настройки экрана и выбрав обои с именем Star Fields мы получим достаточно симпатичное окно в космос. Простейший вариант живых обоев готов к распространению. Этот вариант проекта вы найдете в папке Alfa архива. Недостатки этого варианта очевидны. У пользователя нет настроек количества звезд, поэтому на разных разрешениях экрана будет разная плотность заполнения. Конечно, можно ввести коэффициент плотности на сантиметр экрана — но гораздо удобнее возложить выбор количества звезд на пользователя. Для этого необходимо добавить кнопку настроек.
Сохранять и восстанавливать настройки можно несколькими способами — написав собственную форму и сохраняя данные в файловой системе или используя стандартную форму предпочтений PreferenceActivity. Первый вариант проще для понимания, но добавляет несколько проблем, таких как вопрос где хранить файл с настройками и типизация настроек. Использование PreferenceActivity сложнее, зато обеспечивает стандартный для Android механизм хранения, изменения и восстановления любых пользовательских настроек в приложении, его и реализуем.
Для начала создадим разметку нашего окна предпочтений, для этого в папке ресурсов xml создадим файл star_settings.xml следующего содержания
Среда Eclipse позволяет работать с окнами свойств в режиме редактора, но для одного управляющего элемента проще все написать руками. Внутри разметки PreferenceScreen размещен только один элемент — это поле ввода текста EditTextPreference в котором мы задаем количество звезд. Здесь два основных атрибута android:defaultValue задает значение параметра по умолчанию, а android:key определяет текстовую метку, по которой к этому параметру можно получить доступ. В строковые ресурсы необходимо добавить текст заголовка с именем star_settings. В класс StarFieldsShow необходимо добавить строковую константу SHARED_PREFS_NAME которая будет содержать имя набора настроек, по этому имени мы будем к ним обращаться из класса.
Теперь нам нужен класс для использования нашей разметки. Создадим класс StarSettings наследующий свойства PreferenceActivity, в котором перезагружаем метод onCreate(Bundle icicle)
Важным здесь является привязка набора настроек к ранее заданной константе методом setSharedPreferencesName и установка ресурса формы с настройками addPreferencesFromResource из файла star_settings. При необходимости обрабатывать корректность вводимых данных используется метод onSharedPreferenceChanged, который вызывается при каждом изменении настроек. Так как наша форма настроек будет вызываться на экран, добавляем информацию о ней в AndroidManifest.xml, не забыв добавить ссылку на стиль настройки живых обоев
Для вызова окна настроек нам осталось сделать последний шаг — в файле star_fields.xml добавляем ссылку на класс StarSettings , содержащий настройки.
После сборки этого варианта обоев и установки их на устройство, если выбрать из списка Star Fields, на фоне звездного поля отобразится уже две кнопки — установка обоев и настройка. Выбрав настройку, мы увидим один пункт с именем Star counts, внутри которого находится поле ввода со значением по умолчанию. Если это значение изменить, выйти, а потом войти в настройки повторно, значение сохранится. Но ведь это еще не все, введенный параметр не влияет на количество звезд.
Для работы с сохраненными параметрами, необходимо включить в класс StarFieldsEngine обработку события изменения настроек. Для начала добавим переменную mPrefs, которая послужит ссылкой на класс настроек, потом в определение класса добавим включение метода SharedPreferences.OnSharedPreferenceChangeListener, и определим его в теле класса
Теперь откорректируем тип переменной STAR_MAX (раньше она была константой, убираем квалификатор static), добавим в конструктор класса StarFieldsEngine инициализацию ссылки на объект свойств и установим обработчик события на класс StarFieldsEngine
Вся работа с параметрами осуществляется внутри метода onSharedPreferenceChanged, для начала мы получаем текст введенный пользователем в поле количество, а потом заново инициализируем массив звезд вызвав метод initStars(). Собрав проект, мы получим работающий вариант настроек. Не хватает только обработки исключительных ситуаций, на случай, если пользователь вместо цифр начнет вводить буквы или захочет указать отрицательное количество звезд. В таком случае мы просто заменим число звезд на значение по умолчанию. Реализуем простейшую проверку в методе onSharedPreferenceChanged класса StarFieldsShow. Для этого добавим проверку на выход количества точек из заданных границ и попытку ввести буквы вместо цифр. Корректное значение необходимо вернуть в окно свойств, для этого значение преобразовывается к типу Editor, меняется и возвращает значение параметра после вызова метода commit().
Окончательный вариант проекта находится вархиве, в папке Final. После сборки мы получим работающие обои с окном настроек и защитойих от рук любопытного пользователя.
Источник