Fun With Density Resource Set Qualifiers
The normal rule for resource set qualifiers, like -large
or -land
,
is that only those that match the device’s current configuration will
be used. One oft-mentioned exception to this rule are density
resource set qualifiers, like -hdpi
and -xxhdpi
, where Android will
choose from another “near” resource set if there is no exact match.
This latter capability was always described in the context of drawable resources, where Android has the ability to “convert” a resource from one set to another, such as downsampling an image. Therefore, I had assumed that this resource set trickery was a feature of drawable resources.
It’s not.
It’s a feature of the density resource set qualifiers.
(probably many of you already realized this, or guessed better than I did)
So, for example, if you have an app with res/values/strings.xml
and res/values-xxhdpi/strings.xml
, and you request a string
resource on an -xhdpi
device, my assumption was that you would
get the one from res/values/strings.xml
. After all, you do not
match the density, and Android cannot really convert a string between
densities, so you would get the default. In reality, at least on
Android 4.2, you get the one from res/values-xxhdpi/strings.xml
.
Android
applies the same rules for choosing a resource set based on density
for strings as it does drawables.
Now, in truth, you should not run into this very often. Outside of
maybe some game apps, having layouts or menus or preferences
that vary by screen density is a strong code smell. But if you are
tweaking dimension resources using density resource sets (for cases
where the straight-up dp
conversions do not quite give you what
you want), or similar situations, just bear in mind that all
resources, not just drawables, are affected by the way density resource
set qualifiers are used.
Many thanks to Morrison Chang, whose answer and comments on StackOverflow triggered my research in this area.