18

I am creating a appwidget that consists of a single custom view called Foo.

xml/widget.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>

layout/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>

Foo:

  public class Foo extends View 
  {..}

I tested the Foo view in a normal android app, and it works perfectly. However, when I try to run the widget I get "error while loading widget". When I remove the Foo view from the widget, everything is fine. So it has something to do with the Foo view.

Unfortunately I can't get any more specific errors in DDMS, cause I don't know of a way to debug widgets.

I would like to know if it is indeed possible to use your own custom views in a app-widget? Am I doing something wrong here?

Peterdk
  • 15,625
  • 20
  • 101
  • 140
  • What's in your Foo view? You can only have certain views in a widget. I'm not even sure you can instantiate a widget with a view created with code. – Falmarri Oct 31 '10 at 09:40
  • I had created a totally custom drawn dynamically updated visual thingy. Nice as a widget, but I guess I'll try now to render it to a bitmap in the `provider` and push it to a imageview that is supported. – Peterdk Oct 31 '10 at 10:43
  • Yes. That's exactly same way I did for my widget animation. – xandy Oct 31 '10 at 12:46

4 Answers4

49

I pretty much left my custom view intact, and implemented an ImageView for my widget, then rendered the view using the 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);
Chrispix
  • 17,941
  • 20
  • 62
  • 70
  • 2
    I resolved the issue indeed by using a `ImageView`. I however didn't think of keeping my custom view. I integrated the renderingcode in the `Provider`. This is however a very nice solution! – Peterdk Nov 12 '10 at 23:43
  • In which method should I put this? – vikifor Jul 15 '16 at 07:49
  • It's an amazing solution to use the bitmap of custom view. – Shaw Nov 21 '16 at 15:54
  • 1
    Additional note: If your custom view extends a linear layout, then you need to measure with a maximum height constraint, else it doesn't expand to fill space. – HRJ Jan 20 '17 at 07:23
14

Another way to do this without using 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);

I used cache not to redraw all the view so I couldn't use the code above. And I find it more elegant. I hope it could be useful to someone.

biegleux
  • 13,179
  • 11
  • 45
  • 52
Yoann Delouis
  • 141
  • 1
  • 2
  • I prefer this solution, as getDrawingCache used in the accepted solution is deprecated. In my case it worked better to use `myView.measure(View.MeasureSpec.makeMeasureSpec(500, EXACTLY), View.MeasureSpec.makeMeasureSpec(500, EXACTLY))` – sulai Feb 07 '20 at 15:57
8

You cannot have ANY custom view used in widget. In fact, even those android-predfined views are not all supported.

For detailed list of supported widgets/layouts, please read the documentation. Anything other than those documented cannot be placed in widgets.

xandy
  • 27,357
  • 8
  • 59
  • 64
  • 1
    Wow, that sucks... Why on earth did they do that? – Peterdk Oct 31 '10 at 10:35
  • 2
    Let me guess, since for widget, you (as widget developer) don't own the process/thread that render the widget, indeed, the home screen / launcher owns and renders it. Such limitation applies to prevent FC or poorly programmed widget kills the home screen app. – xandy Oct 31 '10 at 12:50
  • I saw this, and was rather disappointed. I figured there should be a way around it. I decided to share as this thread got my gears turning :) – Chrispix Nov 09 '10 at 20:49
  • @Chris. I feel the same as you. Depending on what you need to do, it might have alternatives. I personally developed a widget that play sprite animation, not that mature but the idea is to compose and swap the appearance using "setBitmap". http://andytsui.wordpress.com/2010/06/06/animating-android-home-screen-widget/ If you look for interactivity other than just 'click', then the standard home could not help, you have to do it in aHome or launcherpro or similar. – xandy Nov 10 '10 at 02:31
8

see the documentation.

AnalogClock, Button, Chronometer, ImageButton, ImageView, ProgressBar and TextView are the supported views. For layouts you have to use FrameLayout, LinearLayout or RelativeLayout.

hanspeide
  • 2,819
  • 4
  • 25
  • 33