Как стать автором
Обновить

Изменение размера виджета в Android 4.1 Jelly Bean

Время на прочтение 3 мин
Количество просмотров 15K
Как стало известно — в новой версии Android Jelly Bean (API v16) появилась возможность изменения размера виджета, да не просто изменения, а автоматического, который теперь подстраивается под свободное место на экране.
Функция удобная и полезная, но в официальной документации про это почти ничего нету, что довольно странно.

Так как я разрабатываю несколько виджетов, то решил добавить данный функционал.


Первое что я заметил, это то, что виджет вообще не меняет размер, это решилось просто добавлением 3 строк в widget_provider.xml (res/xml):

android:resizeMode="horizontal|vertical"
android:minResizeHeight="72dip"
android:minResizeWidth="72dip"

android:resizeMode отвечает за направление изменения размера виджета и имеет 3 возможных значения:
  • horizontal — позволяет растягивать виджет по горизонтали
  • vertical — позволяет растягивать виджет по вертикали
  • none — запрещает растягивать виджет (по умолчанию)

android:minResizeHeight и android:minResizeWidth отвечают за минимальный размер виджета, который можно выставить.
В коде выше виджет можно растягивать в любом направлении и его минимальный размер 1*1 ячейка.

Вроде все стало отлично, и все работает, однако какого размера стал виджет не ясно.
В документации нашел упоминание метода onAppWidgetExtrasChanged(Context context, AppWidgetManager appWidgetManager,int appWidgetId, Bundle newExtras), который должен вызываться при изменении размера, но у меня он так ни разу и не вызвался.
Далее обнаружилось, что при изменении размера виджету отправляется новый броадкаст "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS". Следуя логике можно было предположить, что с ним должен отправиться и новый размер. Так и оказалось.
Но отправляется он не в очень явном виде. В итоге получился такой код:

        final String action = intent.getAction();
        if (action.equalsIgnoreCase("android.appwidget.action.APPWIDGET_UPDATE_OPTIONS")) {

            Bundle b = intent.getBundleExtra("appWidgetOptions");
            int appWidgetMinWidth = (Integer) b.get("appWidgetMinWidth")/80;
         // int appWidgetMaxWidth = (Integer)  b.get("appWidgetMaxWidth");
         // int appWidgetMinHeight = (Integer)  b.get("appWidgetMinHeight");
            int appWidgetMaxHeight = (Integer)  b.get("appWidgetMaxHeight")/100;
		Log.i("Widget","Width="+appWidgetMinWidth+" Height="+appWidgetMaxHeight);

Отправляются 4 размера — минимальная и максимальная ширина и высота. В ходе эксперимента выяснилось, что эти размеры постоянны и удобнее ориентироваться на минимальную ширину и максимальную высоту.
При изменении размера виджета в лог выведется его размер в количестве ячеек. Далее этот размер можно сохранить для данного виджета (его ID: int id = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);) и при обновлении считывать ти данные и подстраивать параметры.

В более ранних версия Android такой функции, естественно, не было, и многие разработчики, да и я в том числе, делали несколько размеров виджета, дабы предоставить людям выбор, теперь этот выбор не нужен, поэтому по хорошему, оставить пользователю с Jelly Bean 1 виджет и функцию масштабирования, а пользователям более ранних версий несколько виджетов с разными размерами, но все это что бы было в 1 пакете.
реализовать это оказалось очень просто:
Создаем в папке res/values файл bool.xml с содержимым

<resources>
    <bool name="v16">true</bool>
</resources>

И в папке res/values-v16 такой же файл, но нескольки иным содержимым:

<resources>
    <bool name="v16">false</bool>
</resources>

После чего в AndroidManifest.xml у ресиверов виджетов, которые необходимо скрыть в новой версии дописываем
android:enabled="@bool/v16"

И все, начиная с API v16 данные виджеты будут отключены, и в списке не отображаться.

P.S. данный метод проверялся на MDPI и HDPI экранах с размером сетки лаунчера 4*4, просьба пользователей планшетов с Android Jelly Bean и размером сетки большим чем 4*4 проверить метод, возможно размеры будут изменяться по несколько другой последовательности.
Теги:
Хабы:
+31
Комментарии 10
Комментарии Комментарии 10

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн