Toss a Coin to your Widget! Or don’t…

Part 2 of 3

Jenni Thieroff
intive Developers
5 min readJul 21, 2021

--

Written by Sarah Will, Jenni Thieroff and Miriam Cordes

A descriptive article image showing a blurred IDE, coins, a smartphone with an installed Home screen widget and a screaming emoji
Toss a Coin to your Widget! Or don’t…¹

Welcome to part two of our article series about Android widgets and their caveats and pitfalls. In the first part, we focused on the use of background processes in the context of widgets. In the second part, we want to highlight what needs to be considered when designing and building the UI of a widget.

Undocumented UI “caching” — why does my widget keep getting bigger?

If you want to update a widget, you set your RemoteViews with a layout id and call matching setters for all views you want to update with the newest information. In the end, you’ll use AppWidgetManager.updateAppWidget() with your appWidgetId.

widgetIds.forEach {
val views = RemoteViews(
packageName,
R.layout.widget_layout
).apply {
// set name
setTextViewText(R.id.vegetableName, vegetable.name)
// set pending intent
setOnClickPendingIntent(R.id.container, pendingIntent)
// set image
val appWidgetTarget =
AppWidgetTarget(context, R.id.vegetableImage, this, it)
Glide.with(context)
.asBitmap()
.load(vegetable.imageUrl)
.into(appWidgetTarget)
}
AppWidgetManager.getInstance(context).updateAppWidget(it, views)
}

Since the creation of an object of RemoteViews looks a lot like a layout inflation in your other app code, you might think that it also acts like inflating a new layout.

But there’s one pitfall: if you called a setter in an earlier update of the widget, this data will still be visible for the next update.

So, e.g., if you add some views to your RemoteViews via addView(), you’ll first have to remove all the old views with the next update (via removeAllViews()), otherwise, the list will only get longer with each update.

The sky is the limit — or is it?

Since the widget layouts are based on RemoteViews you cannot use custom views and you are limited to the following layout and widget classes:

Layout Classes

  • FrameLayout
  • LinearLayout
  • RelativeLayout
  • GridLayout

Widget Classes

  • AnalogClock
  • Button
  • Chronometer
  • ImageButton
  • ImageView
  • ProgressBar
  • TextView
  • ViewFlipper
  • ListView
  • GridView
  • StackView
  • AdapterViewFlipper

This limitation is very cumbersome if your app relies on custom views and/or has a specific design that defines the brand behind your app. Ensure to inform your design team about these limitations and work closely together when developing the widget’s design to keep the implementation of the layout as stress-free as possible.

With Android 12 compound buttons are added to the Widget classes, so checkboxes, switches and radio buttons can now also be used for the widget layout.

Square-y sorry — Why your 2x2 widget is probably not going to be square

Working with the abundance of display sizes is a problem area that every Android Developer is familiar with. Unfortunately, this also affects widgets and although the official documentation addresses sizing of widgets it is not always as simple. The Android Home screen is divided into a grid that consists of several cells. The official documentation states that many handsets offer a 4x4 grid while tablets can offer a larger, 8x7 grid. However, since the documentation is outdated and there are so many different display sizes nowadays, determining your widget’s size is more trial and error than an easy calculation. One thing to keep in mind is that a 2x2 (3x3, 4x4 etc.) widget will probably not be square. According to the documentation, most devices have a 4x4 grid and since standard smartphones are taller than they are wide, the cells are not identical in height and width and therefore not square.

Three screenshots of an Android phone with the widget preview of a widget with the size 2x2, the widget before dropping it on the screen and after dropping it on the screen
Widget preview, widget size of the 2x 2 widget before and after dropping it on the phone screen²
Three screenshots of an Android tablet with the widget preview of a widget with the size 2x2, the widget before dropping it on the screen and after dropping it on the screen
Widget preview, widget size of the 2x 2 widget before and after dropping it on the phone screen²

If your widget does not appear in the preview, check the size of the widget and the available space on the Home screen. Perhaps there is simply not enough space.

Android 12 comes with improved APIs for widget sizes and layouts which should make widget sizes more reliable across different devices and screen sizes. For example, you can now provide responsive or even exact layouts depending on the size of the device.

Nice design with the image as background and rounded corners! Yeah, about that…

So, the design team decided to make a good-looking widget with rounded corners and a background image matching the widget’s size which is loaded from the backend. In the beginning, you might see this as not too difficult to implement.

Typically, a CardView could be used for that, but CardViews are not an option for widgets, as we already learned.

You might want to apply a transformation to the image via the tool you load your images with. For example, Glide has a transformation to add rounded corners. For this to work (and still have an image that isn’t distorted) you’ll need the size which is needed for your image beforehand. And we already heard about the pain of widget sizing.

With normal views, you could also use the method setClipToOutline(true) in an ImageView which has a background (not src) with rounded corners. But widgets don’t support all methods normal views support, so this won’t work either.

In the end, we decided to make a widget without rounded corners.

We were surprised to hear that rounded corners are the default for widgets on Android 12, but at least in the future, no one will have to rack their brains to use rounded corners on an image that is loaded from the backend and that is then used as the background of the widget.

That was all for the second part of our series of articles on Android widgets. Be on the lookout for part three, where we investigate how to debug widgets, what you should keep in mind as soon as your widget is live and much more.

[1]: Emoji by Noto Emoji fonts
[2]: Photo of carrots by Chokniti Khongchum from Pexels

--

--