Seven rules I rewrote 13 home-screen widgets against, after placing them next to Samsung's
Putting 13 widgets from 5 apps on a real home screen beside Samsung's weather and wallet widgets showed that "the code exists" and "it looks like a shipped product" are very different. System dark mode, designed empty states, previewLayout and label, dp corner radii, and the theme lag of bitmap widgets.
A widget does not live inside your app; it lives on someone else's screen. So whether it is any good is decided not inside the app but on the home screen, next to Samsung's and Google's widgets. I placed 13 widgets from 5 apps (3 from the ad-revenue app, 6 from the exam countdown app, 2 sunrise/sunset, 1 screen time, 1 pet care) exactly like that, and there was a lot to fix.
1. Follow the home screen's dark mode
One app's widget followed the app's own theme setting. Home screen dark, widget bright. A widget must follow system dark mode. Split colors with values-night resources and RemoteViews picks them up.
Widgets drawn as bitmaps (charts, calendar grids) have a limit: when the theme changes, the old image stays until the next update, up to 30 minutes. That cannot be fixed; know it and move on.
2. Design the empty and no-permission states
A single grey line saying "No data" gets clipped in a 2×2. Use an icon, a title and one wrapped line of guidance. No location permission, no records yet, freshly installed: each state has to be looked at on a real device.
3. previewLayout and the receiver label
One app showed only its icon in the widget picker, because android:previewLayout was missing. Another app's six widgets all appeared under the same name in the picker. Give each receiver its own android:label.
previewLayout renders XML without running any code. Point it at the real widget layout and the preview shows blanks, so keep a separate preview copy of the layout with sample values baked in.
4. Fill empty space, drop the app-name header
Grid widgets re-flow their cells to the item count; empty list rows become a dashed "+ add" row; a 4×2 gets a secondary line (weekday/weekend, for instance). A number widget is one big number, a colored pill for the delta, and a 7-day bar, and that is enough.
Conversely, do not put the app name as a header line at the top. Samsung's widgets do not have one, and once placed, that line is exactly where "home-made" shows.
5. Place names instead of coordinates
Nobody reads latitude and longitude on a location widget. Reverse-geocode to a place name, cache it, and fall back to "My location" on failure.
6. Corners in dp, padding proportional
I had computed the corner radius as a ratio ("slider 40 = semicircle"), which produced a pill a quarter of the widget's width on large sizes. Corners are a fixed ~20dp, with 1×1 capped at 22% of the short side. Fixed 12px inner padding puts text against the corners on large cards; scale it with the cell. If a grid has a single item, show the card alone without a backing plate; a plate with one card looks like a border.
7. The crescent on preview PNGs
Cutting a preview image out of a dark-background capture leaves crescent-shaped background in the corners. Re-mask with the card radius. Keep dark versions in drawable-night-nodpi.
Only RemoteViews-supported views
There was a case where the build passed but the widget would not load at all. The cause was a single <View> used as a divider. RemoteViews accepts only its supported view classes, and one unsupported view stops the whole widget from loading. Use an ImageView or a FrameLayout with a background for dividers.
How I check
On a physical phone (Galaxy Note10, One UI) I place each widget on the home screen and look at four shots: light and dark, real data and empty state. One thing I learned while automating placement: if the widget's configure activity appears, you must tap Save or the widget is deleted when you go home.
Two apps (screen time and pet care) already met these rules and were left alone.
Summary
- Judge widgets on the home screen, next to shipped widgets.
- System dark mode, designed empty states, previewLayout + label, dp corners, proportional padding.
- No app-name header line.
- RemoteViews-supported views only; one
<View>kills the whole widget. - Look at light/dark × data/empty, four shots, on a real device.