The symptom
You design an Android widget to occupy a single grid row. You set the modern cell-count hint and the legacy dp fallback, you test on a Pixel, it looks right. Reviews start coming in from users on a different brand: the widget is taking up two rows on their home screen, and it won't shrink. It resizes horizontally fine; vertically the minimum is stuck at two cells.
Same APK, same descriptor, completely different rendered size. That's because Android doesn't have one widget-sizing system — it has two, and they don't agree.
Two sizing systems on the same descriptor
Every widget ships an <appwidget-provider> XML descriptor. How many grid cells the launcher actually gives that widget depends on which sizing system the launcher uses:
- Legacy — all Android versions.
minWidthandminHeightin dp. The launcher converts dp to a cell count via a formula and rounds up. The number of cells you get is not the literal dp value — it's a derived quantity. - Modern — Android 12 / API 31+.
targetCellWidthandtargetCellHeightas integer cell counts. On launchers that implement the modern path, these are used directly and the dp fields are ignored for the default placement. The Android docs say explicitly: “If defined, these attributes are used instead of minWidth or minHeight.” (Android Developers: Provide flexible widget layouts).
Most apps set both, treating dp as the universal fallback for pre-API-31 launchers. The trouble starts when the two disagree — or when a launcher that should use the modern path still leans on the legacy dp values for its rounding.
Two published formulas, and they don't agree
Android has published two differentdp↔cell rules over the years, and both are still cited in the wild:
| Era | Formula (1 dimension) | 1 cell | 2 cells | 3 cells |
|---|---|---|---|---|
| Older App Widget Design Guidelines | 70n − 30 | 40dp | 110dp | 180dp |
| Current Provide flexible widget layouts | 73n − 16 (W), 118m − 16 (H) | 57 / 102dp | 130 / 220dp | 203 / 338dp |
These disagree badly in the danger zone. Take a widget with minHeight = 70dp:
- Old formula:
cells = ceil((70 + 30) / 70) = ceil(1.43) = 2 rows. - Current formula:
(70 + 16) / 118 = 0.73 → 1 row.
Whether 70dpmeans “1 row” or “2 rows” depends entirely on which model the launcher implements. The Android docs themselves call these numbers estimates“for a typical 5×4 grid handset” — i.e. the dp↔cell mapping is explicitly not standardized.
Why the same widget looks fine on Pixel but wrong elsewhere
Picture a widget with minHeight = 70dp and targetCellHeight = 1. Across three launchers you get three different outcomes:
| Launcher | What it does | Result for 70dp |
|---|---|---|
| Pixel (AOSP Launcher3, A12+) | Honors targetCellHeight; ignores minHeight for default placement. | 1 row |
| Samsung One UI | Still weighs minHeight against its ~72dp cell. 70 < 72, by a hair. | 1 row — barely |
| Sony Xperia (21:9) | Leans on minHeight with a shorter effective cell and stricter rounding. | 2 rows |
A useful mental model: a launcher effectively picks max(targetCellHeight, minHeight-converted-to-cells). Pixel's first term wins. Samsung's two terms tie at 1. Sony's second term wins at 2.
The Samsung history is instructive. An earlier change once bumped minHeight from 70dp to 80dpto fix text clipping — and broke Samsung, because 80dp > 72dp cell forced a second row. The real clipping fix turned out to be lineSpacingExtra on the text views; the height bump was an unrelated regression. Restoring 70dp fixed Samsung. The lesson: 70dp only “works” on Samsung by sitting just under its cell height — it's a value balanced on a knife's edge, not a robust choice.
The Sony Xperia 21:9 case — and the Firefox precedent
Sony Xperia phones use an ultra-wide 21:9 display, and Sony's launcher applies a denser grid where this rounding turns into a hard 2-row minimum for widgets that everyone else shows as one row. This isn't app-specific — it's a launcher-class quirk. Mozilla's Firefox hit the identical bug:
Firefox issue #26965 — “Search widget has height of 2 cells on Sony Xperia phone(s?).” Sony Xperia 10 IV, Android 12. The widget is expected to be 1 cell high but Sony's launcher renders it 2 cells; it resizes horizontally to 1 cell but cannot be resized vertically. Diagnosed as Sony's launcher enforcing a 2-cell minimum height tied to the 21:9 grid. Labeled minor cosmetic (S4) and shipped unfixed — Mozilla never found a minHeight workaround worth taking (mozilla-mobile/fenix#26965).That a team Mozilla's size hit this and declined to fix it is the single most important data point: there is likely no clean, config-only cure that's guaranteed across Sony's fleet.
The fix worth attempting — and what it doesn't guarantee
The standard remedy is to set the widget's minHeight and minResizeHeight to the canonical 1-cell value of 40dp so that both sizing systems agree on one row:
- Modern launchers keep using
targetCellHeight = 1→ 1 row (unchanged). - Legacy launchers compute
ceil((40 + 30) / 70) = 1 row. - Samsung:
40 < 72→ still 1 row, and now well clear of the 72dp danger line. - Lowering
minResizeHeightto 40dp also lets users manually drag a stuck widget back down to one row.
Worth flagging: minHeight is only a floor— the launcher still hands the widget a full cell, so content renders at full cell height. 40dp does not make the widget visually shorter.
Open caveats (don't overclaim)
- Because the dp↔cell mapping isn't standardized, 40dp is a well-grounded attempt, not a guaranteed fix. If Sony's launcher imposes a hard 2-row floor regardless of hints, no dp value escapes it — the
minResizeHeightchange would then only enable a manual workaround, not a correct default. - This must be verified on a physical Sony Xperia (or a 21:9 Xperia on a cloud device farm running Sony's own launcher — a generic AOSP launcher won't reproduce it).
- Already-pinned widgets keep their current grid size; only new placements pick up corrected sizing.
Practical takeaways for widget developers
- Always set both
targetCellWidth/Height(modern) andminWidth/minHeight(legacy fallback), and make them agree using the70n − 301-cell values — 40, 110, 180 dp … - Avoid
minHeightvalues that the two formulas disagree on — e.g. 70dp lands at 1 row under the current formula but 2 rows under the legacy formula. - Fix text clipping with
lineSpacingExtraor padding, not by inflatingminHeight. - Test on more than a Pixel. Samsung One UI and Sony Xperia (21:9) interpret the same descriptor differently; the cheapest coverage is a real-device cloud (BrowserStack carries no Sony; LambdaTest carries 21:9 Xperia models).
Sources
- Android Developers — Provide flexible widget layouts
- Android Developers (archived) — App Widget Design Guidelines (
70n − 30rule) - Do more with your widget in Android 12 (
targetCellWidth/Height) - Mozilla Firefox (Fenix) issue #26965 — Sony Xperia 2-cell widget
- romannurik/AndroidAssetStudio #16 — widget size calculator (formula reference)