Implementing Resource Sets

Ideally, that strategy would be sufficient. Unfortunately, things are not quite that simple. So, let’s walk through some common configurations and associated resource sets, to see how we can set them up.

Language

As noted above, you can have different resource sets for different languages, by adding the language code as a suffix on the resource directory name. Usually, this is just applied to res/values/ (e.g., res/values-es/), as usually the only things that change in an app based on language are string resources. In principle, though, you could use such language suffixes on any resource directory (e.g., res/raw/ for English-language audio clips and res/raw-es/ for Spanish-language audio clips).

However, languages often vary by region:

To address this, Android supports two different systems for regional localization.

The classic approach was to add an ISO-3166-1 alpha-2 code after the language code and prefixed by r (for “region”). For example, US English is res/values-en-rUS/, while UK English is res/values-en-rGB/ (“GB” for “Great Britain”).

Android 7.0 and higher support BCP 47 language and locale values as an alternative system. Those get an overall b+ prefix, to distinguish them from other resource set qualifiers. In the BCP 47 approach, English is res/values-b+en/, while US English is res/values-b+en+US/ and UK English is res/values-b+en+GB/. However, this system has not been as popular, in part because we have so much history with the original system.

In either case, string resource sets are additive. You do not need to have a full set of US English strings and a full set of UK English strings to support full localization, because many of those strings will be in common. Plus, you can choose one of the regions to be the default for a particular language, so you only need resource sets and overrides for the specific strings that you need for the specific locales that concern you.

So, for example, you could have:

Note that Android Studio has a translations editor to help you manage your string resources for your default language and whatever translations you are going to include in your app.

Screen Size and Orientation

The resource sets that get the most attention are those for screen size (and, secondarily, screen orientation).

Android “borrows a page” from Web development. Web content nowadays uses CSS media queries to have different layout rules based on screen size, typically screen width. Similarly, Android allows you to set up different resource sets to use for screens with varying sizes, where you choose the size. And, like CSS media queries, you can choose the dividing lines between different rules — you are not limited to some fixed set of size buckets.

There are three families of qualifiers that you can use:

The difference between -wNNNdp and -swNNNdp is that -wNNNdp is based on the current width, and the current width of a device depends on its orientation. -swNNNdp, by contrast, cares only what the length of the shorter screen dimension is (“smallest width”) and therefore is independent of orientation.

So, you could have:

Hey, What About res/layout-large?

You will see references to other size-related resource set qualifiers: -small, -normal, -large, and -xlarge. This was the original system used by Android. However, it was not very flexible. Android 3.2 added the system described above, and so most modern Android app development should use that system.

Hey, What About res/layout-land?

Similarly, you will see references to a -land suffix to be used for landscape resources. So res/layout/ would be used for portrait layouts and res/layout-land/ would be used for landscape layouts.

Frequently, though, we do not care about the actual orientation, only the width (or maybe the height). For example, many Web sites that use CSS media queries apply different CSS rules based on the viewport width. While most computer monitors are landscape, some can be rotated to portrait — the CSS media queries do not care and only differentiate based on width.

As a result, while -land exists and can be used, you will not see it quite as much as you might have in the early days of Android app development.

API Level

Earlier in the book, we saw res/drawable-v24/ as a resource directory. This follows the same resource set system, where -vNN, for some value of NN, means “use these resources on devices running API Level NN or higher”. So, res/drawable-v24/ will be used on API Level 24+ devices and will be ignored on older devices.

Screen Density

Similarly, we saw various mipmap directories, like res/mipmap-hdpi/ and res/mipmap-xhdpi/. This too follows the same resource set system, where -hdpi says “these resources were optimized for HDPI screens”, while -xhdpi says “these resources were optimized for XHDPI screens”.

The Full Roster

There are lots of different resource set qualifiers.

The full roster can be found in the Android developer documentation. In particular, “Table 2” in that section lists all of the current candidates.

Note that resource set qualifiers get added from time to time. For example, the -wNNNdp family of screen size qualifiers was added in API Level 13 (Android 3.2). The table points out what version of Android added support for those qualifiers. Older devices will not crash if they encounter those qualifiers, simply ignoring them instead.


Prev Table of Contents Next

This book is licensed under the Creative Commons Attribution-ShareAlike 4.0 International license.