For those who don't know, Mike & I make a popular widget app for Android called HD Widgets. We've spent a lot of time resolving for Android UI fragmentation and have been mostly successful.
Recently we made the jump to the latest Android sdk (15). We did this to take advantage of the new features and give HD Widgets a long runway. Unfortunately, the "creative" folk behind Android decided to throw a new curve-ball that started with sdk 14: forced widget margins:
Note: As of Android 4.0, app widgets are automatically given margins between the widget frame and the app widget's bounding box to provide better alignment with other widgets and icons on the user's home screen. To take advantage of this strongly recommended behavior, set your application's targetSdkVersion to 14 or greater.
While they say "strongly recommended", it's actually a forced feature. This is a setting you have no control over - it's automatically added and you can't change it.
What does this mean? It may seem like a small change but it will have a dramatic effect on your layouts. Essentially if you build using the ICS APIs, widgets are reduced in size by ~15% on ICS devices and *only ICS devices* ! While this was implemented solely to make Google's Launcher look better, it affects all launchers on the device.
Here's what you'll see if you use the new sdk and use the built-in margins:
The best solution for backwards size-compatibility is to use @dimen to assign dynamic padding depending on OS version. So each of our widgets has this as our base layout:
From here we create two dimens.xml files, one for your values folder, and the other for values-v14:
[crayon lang="html" title="values/dimens.xml"]
[crayon lang="html" title="values-14/dimens.xml"]
The key here is that all devices get an extra 6dp of padding, but we revert that to 0dp for v14 devices so they only get the native padding.
Final Tip: remember that the xml value is singular: dimen but the file name is plural: dimens.
New Issues (the size war)
While this solution works great for backwards-compatibility there's a many upcoming issues that you'll need to be aware of which are unique to ICS devices.
The most critical issue is that widget sizes are going to vary greatly between manufacturers. Samsung wants full screen-width sizing, HTC wants large but with a little padding, and Asus & Motorola seem to want to keep the tiny Nexus-like sizing.
The size inconsistency trickles down to third party launchers and ROMs. For example here's the grid size difference between the native launcher and ADWLauncher EX on the Galaxy Nexus:
Similar to Honeycomb, the new ICS launcher's grid isn't actually full screen. The native ICS launcher features a non-removable Google Search Bar on the top. To keep the grid layout proportional, they reduce the total grid size by 20%. That causes another dramatic size difference between layouts of launchers even on the same device.
There's also a major bug introduced in ICS 4.0.3 (at least for tablets) whereby widgets are given the same height as app icons. Until this release widgets we as high as the icon plus text. This bug reduces the height of ICS tablet widgets to 72 pix from 90 pix - basically 25% shorter (along with the extra padding).
The last issue introduced by ICS's new widget margins is that sometimes the native launcher hiccups and forgets to auto-apply the margins, resulting in unsightly bloated widgets:
I've seen this pop up a few times. I don't know why & I haven't found a pattern. Needless to say, you may get feedback from your users about this so it's useful to know it happens.
[Update 4/24/12: changed the code from using multiple RemoteViews to using @dimen padding. The RemoteViews method seemed to work fine and offered more flexibility, but @dimen is part of the Developer Documentation so it is less likely to break in the future.]
[Update 6/12: after launching HD Widgets 3.0 we discovered that some manufacturers ignore the setting, as well as the 4.0.3 shrunken widget bug. Updated accordingly.]