Виджеты представляют собой миниатюрные приложения, которые располагаются на домашнем экране устройства под управлением операционной системой Android.
Виджеты могут показывать время, погоду, курсы валют и другую полезную информацию. Также виджеты могут выполнять какие-либо действия.
Виджеты очень удобны благодаря быстрому доступу. Однако в силу того, что размер экрана мобильного устройства весьма ограничен, использование виджетов оправдано только для отображения действительно важной информации или доступа к часто используемым функциям.
Создание виджета можно условно разделить на две части.
- Описание виджета;
- Реализация программной логики.
1.Описание виджета
Описание виджета содержит информацию о его параметрах, внешнем виде.
Описание состоит из трёх частей
- Объявление виджета в манифесте;
- Создание xml файла с основными параметрами;
- Создание xml файла разметки внешнего вида (интерфейса пользователя).
Объявление виджета в манифесте представляет собой секцию receiver, которая включает ключевую информацию о виджете.
1 |
А, именно (сверху вниз):
- Имя виджета;
- Интент фильтр для события, на которое будет реагировать виджет;
- Секция метаданных. Содержит информацию о том, что компонент, описываемый данной секцией receiver, является виджетом, а также имя xml файла с его параметрами.
Файл параметров виджета находится в папке xml и носит название имявиджета_info. Он состоит из единственной секции appwidget-provider. Параметры указываются в качестве атрибутов этого тега.
Например:
1 |
Эти параметры означают (сверху вниз):
- Файл разметки внешнего вида (интерфейса пользователя) для экрана блокировки (keyguard);
- Файл разметки внешнего вида (интерфейса пользователя) для использования в обычном режиме;
- Минимальная высота виджета;
- Минимальная ширина виджета;
- Изображение значка виджета для меню приложений;
- Возможность изменения размера виджета по горизонтали или вертикали. В данном примере включена возможность изменения размера виджета в обоих направлениях;
- Период обновления данных виджета в миллисекундах. Может быть указано любой число, но обновляться виджет будет не чаще 1 раза в 30 минут.
Файл разметки внешнего вида расположен в папке layout и в принципе ничем не отличается от аналогичных файлов, например, для Activity. Разве, что значения свойств ответственных за внешний вид по умолчанию адаптированы для виджета.
Пример:
1 |
2.Реализация программной логики работы виджета
Виджет является наследником класса AppWidgetProvider, который в свою очередь является наследником класса BroadcastReceiver, добавляя необходимый функционал.
В классе AppWidgetProvider предусмотрена группа из пяти методов, так называемого, «жизненного цикла» виджета, которые нужно переопределить в классе, описывающем конкретный виджет.
- onEnabled
Вызывается только один раз, когда экземпляр виджета создаётся впервые. То есть, когда пользователь добавляет виджет на домашний экран; - onDeleted
Вызывается каждый раз когда экземпляр виджета удаляется из коллекции виджетов; - onDisabled
Вызывается при удалении последнего экземпляра виджета; - onUpdate
Вызывается когда необходимо обновить виджет согласно временному интервалу указанному в параметре updatePeriodMillis или по команде из программы (есть альтернативный подход к обновлению); - onReceive
Вызывается перед каждым из вышеперечисленных методов и при получении Broadcast Intent. Используется, в основном, для реализации обработки событий.
Единственный из методов «жизненного цикла», который не требуется обязательно переопределять.
Главную роль в работе виджета играют два метода: onUpdate и onReceive. Именно они обеспечивают большую часть его функционала.
Как уже отмечено выше, метод onUpdate выполняет обновление виджета – отображение актуальной версии тех или иных данных виджетом, расположенным на домашнем экране устройства.
Обновление виджета достаточно сложный процесс. Но, так как он уже был подробно описан в предыдущих статьях, не станем заострять на нём внимание.
Статьи, посвящённые обновлению виджетов:
- Обновление виджета для домашнего экрана Android по таймеру;
- Обновление виджета для домашнего экрана Android по запросу из приложения.
Для того чтобы обработать в коде виджета те или иные события, нужно задействовать метод onReceive и отфильтровать в нём соответствующий Intent.
Дело в том, что метод onReceive реагирует практически на все broadcast intent’ы, на которые способен реагировать данный конкретный виджет. Поэтому необходимо проверить, какой именно Intent поступил и только после этого выполнять действия.
1 2 3 4 5 6 7 |
public static String ACTION_WIDGET_ RECEIVER = "WidgetReceiver"; . . . public void onReceive(Context context, Intent intent){ if (ACTION_WIDGET_RECEIVER.equals(intent.getAction())) { //Если это нужный Intent, делаем что-то } } |
К сожалению, только таким образом можно обеспечить селективность обработки Intent.
Приведённый механизм используется также для обработки событий пользовательского интерфейса. Для этого на соответствующие элементы виджета устанавливается PendingIntent, который обрабатывается в onReceive.
Ниже представлен пример реализации обработки события клика по текстовой надписи на виджете.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
public static String ACTION_WIDGET_CLICKED = "ClickWidget"; . . . public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.info_widget); Intent clickIntent = new Intent(context,InfoWidget.class); clickIntent.setAction(ACTION_WIDGET_CLICKED); PendingIntent clickPendingIntent = PendingIntent.getBroadcast(context,0,clickIntent,PendingIntent.FLAG_UPDATE_CURRENT); views.setOnClickPendingIntent(R.id.appwidget_textContent,clickPendingIntent); appWidgetManager.updateAppWidget(appWidgetId, views); } public void onReceive(Context context, Intent intent){ if (ACTION_WIDGET_CLICKED.equals(intent.getAction())) { //Если это нужный Intent, делаем что-то } } |
Здесь важно отметить, ещё одну характерную особенность виджетов. Их внешний вид, описанный в файле разметки, доступен только при помощи объекта RemoteViews. Это обусловлено тем, что визуальное представление виджетов работает в другом процессе – процессе домашнего экрана. Вследствие этого обращение к нему напрямую, как в Activity, невозможно.
RemoteViews призван решить данную проблему, но возможности работы с элементами внешнего вида несколько ограничены. Однако их вполне хватает для реализации несложного функционала, для которого виджеты собственно и предназначены.
Всё-таки задача виджетов лишь дополнить основное приложение и сделать его использование более удобным.
Кроме того виджеты работают практически постоянно (кроме периода, когда устройство находится в спящем режиме). При этом дополнительная функциональная нагрузка часто сказывается на продолжительности работы устройства без подзарядки.
Наряду с уже упомянутым в самом начале ограниченным размером экрана, это те причины, по которым крайне не рекомендуется размещать в виджетах сложные алгоритмы. Для них лучше использовать Activity или службы (для фоновых задач). А, виджеты оставить только для отображения важной информации и быстрого доступа к основным функциям приложения.
Добавить комментарий