Android: AppWidget с пользовательским представлением не работает

Я создаю виджет приложения, состоящий из одного пользовательского представления с именем Foo.

xml/виджет.xml:

<appwidget-provider
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:minWidth="294dp"
 android:minHeight="72dp"
 android:updatePeriodMillis="0"
 android:initialLayout="@layout/widget_layout">
</appwidget-provider>

макет/widget_layout

<LinearLayout
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 <package.name.Foo
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 />
</LinearLayout>

Фу:

  public class Foo extends View 
  {..}

Я протестировал представление Foo в обычном приложении для Android, и оно отлично работает. Однако, когда я пытаюсь запустить виджет, я получаю "error while loading widget". Когда я удаляю представление Foo из виджета, все в порядке. Так что это как-то связано с представлением Foo.

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

Я хотел бы знать, действительно ли возможно использовать ваши собственные представления в виджете приложения? Я делаю что-то не так здесь?


person Peterdk    schedule 31.10.2010    source источник
comment
Что находится в вашем представлении Foo? Вы можете иметь только определенные представления в виджете. Я даже не уверен, что вы можете создать экземпляр виджета с представлением, созданным с помощью кода.   -  person Falmarri    schedule 31.10.2010
comment
Я создал полностью индивидуально нарисованный динамически обновляемый визуальный элемент. Хорошо, как виджет, но я думаю, что сейчас я попытаюсь отобразить его в растровое изображение в provider и отправить его в поддерживаемое изображение.   -  person Peterdk    schedule 31.10.2010
comment
да. Точно так же я сделал для анимации виджета.   -  person xandy    schedule 31.10.2010


Ответы (4)


Я в значительной степени оставил свое собственное представление нетронутым и реализовал ImageView для своего виджета, а затем визуализировал представление с помощью getDrawingCache().

MyView myView = new MyView(context);
myView.measure(150,150);
myView.layout(0,0,150,150);
myView.setDrawingCacheEnabled(true);
Bitmap bitmap=myView.getDrawingCache();
remoteViews.setImageViewBitmap(R.id.dial, bitmap);
person Chrispix    schedule 09.11.2010
comment
Я действительно решил проблему, используя файл ImageView. Однако я не думал о сохранении своего пользовательского вида. Я интегрировал код рендеринга в файл Provider. Однако это очень хорошее решение! - person Peterdk; 13.11.2010
comment
В какой метод я должен поместить это? - person vikifor; 15.07.2016
comment
Это отличное решение для использования растрового изображения пользовательского вида. - person Shaw; 21.11.2016
comment
Дополнительное примечание. Если ваш пользовательский вид расширяет линейный макет, вам необходимо измерить максимальную высоту, иначе он не расширится, чтобы заполнить пространство. - person HRJ; 20.01.2017

Другой способ сделать это без использования getDrawingCache() :

MyView myView = new MyView(this);
myView.measure(500, 500);
myView.layout(0, 0, 500, 500);
Bitmap bitmap = Bitmap.createBitmap(500, 500, Bitmap.Config.ARGB_8888);
myView.draw(new Canvas(bitmap));
remoteViews.setImageViewBitmap(R.id.imageView, bitmap);

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

person Yoann Delouis    schedule 15.08.2012
comment
Я предпочитаю это решение, так как getDrawingCache, используемый в принятом решении, устарел. В моем случае лучше использовать myView.measure(View.MeasureSpec.makeMeasureSpec(500, EXACTLY), View.MeasureSpec.makeMeasureSpec(500, EXACTLY)) - person sulai; 07.02.2020

см. документацию.

AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar и TextView являются поддерживаемыми представлениями. Для макетов вы должны использовать FrameLayout, LinearLayout или RelativeLayout.

person hanspeide    schedule 31.10.2010
comment
Ведь и подклассы тех (даже своих) НЕ поддерживаются. - person Peterdk; 31.10.2010

Вы не можете использовать ЛЮБОЕ пользовательское представление в виджете. На самом деле, даже те представления, которые предопределены для Android, не все поддерживаются.

Подробный список поддерживаемых виджетов и макетов см. в документации. . В виджеты нельзя помещать ничего, кроме задокументированного.

person xandy    schedule 31.10.2010
comment
Вау, это отстой... С какой стати они это сделали? - person Peterdk; 31.10.2010
comment
Позвольте мне угадать, поскольку для виджета вы (как разработчик виджета) не владеете процессом/потоком, который отображает виджет, действительно, домашний экран/пусковая установка владеет и отображает его. Такое ограничение применяется для предотвращения того, чтобы FC или плохо запрограммированный виджет убивали приложение на главном экране. - person xandy; 31.10.2010
comment
Я увидел это, и был довольно разочарован. Я подумал, что должен быть способ обойти это. Решил поделиться, так как эта тема завела меня в тупик :) - person Chrispix; 09.11.2010
comment
@Крис. Я чувствую то же, что и ты. В зависимости от того, что вам нужно сделать, у него могут быть альтернативы. Я лично разработал виджет, который воспроизводит анимацию спрайтов, не такой уж зрелый, но идея состоит в том, чтобы составить и поменять внешний вид с помощью setBitmap. andytsui.wordpress.com/2010/06/06 / Если вы ищете интерактивность, отличную от простого «клика», то стандартная домашняя страница не может помочь, вы должны делать это в aHome или launcherpro или подобных. - person xandy; 10.11.2010