Пользовательский виджет приложения для Android

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

Однако, Я столкнулся с несколькими препятствиями в этом процессе.

1) Есть ли способ найти максимально доступное пространство для виджета приложения? (ИЛИ: Можно ли правильно рассчитать размеры для минимального доступного пространства в случаях WVGA (или аналогичных широких)?

Я не знаю, как рассчитать максимальное доступное пространство для виджета приложения. С обычным виджетом приложения можно fill_parent, и все пространство будет использовано. Однако при рендеринге виджета в виде растрового изображения и во избежание растяжения необходимо вычислять правильные размеры. В документации описывается, как рассчитать минимальные размеры, но для таких случаев как WVGA, в ландшафтном режиме будет неиспользуемое пространство, из-за чего виджет будет выглядеть короче, чем другие виджеты, которые растягиваются естественным образом.

float density = getResources().getDisplayMetrics().density;
int cx = ((int)Math.ceil(appWidgetInfo.minWidth / density) + 2) / 74;
int cy = ((int)Math.ceil(appWidgetInfo.minHeight / density) + 2) / 74;
int portraitWidth = (int)Math.round((80.0f * cx - 2.0f) * density);
int portraitHeight = (int)Math.round((100.0f * cy - 2.0f) * density);
int landscapeWidth = (int)Math.round((106.0f * cx - 2.0f) * density);
int landscapeHeight = (int)Math.round((74.0f * cy - 2.0f) * density);

Вычисление cx и cy дает количество горизонтальных и вертикальных ячеек. Вычитание - 2 из рассчитанного dpi (например, 74 * cy - 2) позволяет избежать случаев, когда результирующее количество пикселей округляется в меньшую сторону. (Например, в ландшафтном режиме на Nexus One высота составляет 110, а не 111 (74 * 1,5).

2) При назначении растрового изображения для ImageView, который используется как часть RemoteViews для просмотра изображения, есть 2 метода:

2.1) С помощью setImageViewUri и сохранения растрового изображения в файл PNG. Затем изображение обслуживается с использованием реализации openFile () в ContentProvider:

@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
    // Code to set up imageFileName
    File file = new File(getContext().getCacheDir(), imageFileName);
    return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
}

Это работает, и я использую этот подход в настоящее время. Однако, если я устанавливаю scaleType ImageView на «center», что, согласно документации, должно «центрировать изображение в представлении, но не выполнять масштабирование», изображение масштабируется неправильно. Установка плотности растрового изображения на DENSITY_NONE или getResources (). getDisplayMetrics (). densityDpi не имеет никакого значения при сохранении растрового изображения в PNG, кажется, что он игнорируется, когда файл загружается ImageView. В результате изображение уменьшается из-за проблем с dpi. Кажется, это описывает случай:

http://code.google.com/p/android/issues/detail?id=6957&can=1&q=widget%20size&colspec=ID%20Type%20Status%20Owner%20Summary%20Stars

Поскольку использовать scaleType: center невозможно, единственный способ, который я нашел для работы, - это статическая установка layout_width и layout_height ImageView на заданное количество dpis, а затем рендеринг растрового изображения с тем же dpi. Это требует использования scaleType: fitXY. Этот подход работает, но это очень статичная настройка - и он не будет работать для виджетов приложения 3.1 с изменяемым размером (я еще не тестировал это, но если onUpdate () не вызывается при каждом изменении размера, это верно).

Есть ли способ загрузить изображение в немасштабированный ImageView, или это невозможно из-за ошибки в структуре?

2.1) Автор напрямую используя setImageViewBitmap. Используя этот метод с параметром Bitmap.DENSITY_NONE на растровом изображении, изображение может отображаться без правильного масштабирования. Проблема с этим подходом заключается в том, что существует ограничение на то, как большие изображения могут быть установлены с помощью механизма IPC:

http://groups.google.com/group/android-developers/browse_thread/thread/e8d84920b999291f/d12eb1d0eaca93ac# 01d5c89e5e7b4060

(больше ссылок запрещено) http://groups.google.com/group/android-developers/browse_thread/thread/b11550601e6b1dd3#4bef4fa8908f7e6a

Я попытался немного взломать эту проблему, путем разделения виджета на матрицу изображений, которая может быть установлена ​​блоками 100x100 пикселей. Это позволяло работать с более крупными виджетами, но в итоге оказалось очень тяжелым и не удалось на больших виджетах (4x4).

Извините за очень длинный пост. Я попытался объяснить несколько различных проблем, возникающих при попытке использовать виджет приложения с растровым изображением. Мы будем очень признательны, если кто-нибудь попытался сделать то же самое и нашел какие-либо решения этих проблем или у вас есть полезные комментарии.

7
задан alain.janinm 6 May 2012 в 15:27
поделиться