In Android, almost everything is a resource. Resources are used for anything from defining colors, images, layouts, menus, and string values. The value of this is that nothing is hardcoded. Everything is defined in these resource files and then can be referenced within your application's code.
Since it is not always possible to develop a single design that will scale to fit every screen size, density, and orientation, Android OS provides us with the ability to create our own resource folder (/res) layout subfolder names, so that we can provide custom UI designs for different screen sizes and orientations. Android looks at our user’s screen characteristics at run-time, and selects the correct UI design, based on layout folder naming.
The following are the most common types of resources within Android apps
Name | Folder | Description |
---|---|---|
Property Animations | animator | XML files that define property animations. |
Tween Animations | anim | XML files that define tween animations. |
Drawables | drawable | Bitmap files or XML files that act as graphics |
Layout | layout | XML files that define a user interface layout |
Menu | menu | XML files that define menus or action bar items |
Values | values | XML files with values such as strings, integers, and colors. |
In addition, note the following key files stored within the values folder mentioned above:
Name | File | Description |
---|---|---|
Colors | res/values/colors.xml |
For color definitions such as text color |
Dimensions | res/values/dimens.xml |
For dimension values such as padding |
Strings | res/values/strings.xml |
For string values such as the text for a title |
Styles | res/values/styles.xml |
For style values such as color of the AppBar |
For the full list of resource types, check out the Providing a Resource guide.
There are four important rules to remember when creating alternative resources:
strHelpText
in the /res/values/strings.xml
file, it must be named the same in the /res/values-fr/strings.xml
(French) and /res/values-zh/strings.xml
(Chinese) string files. The same goes for all other types of resources, such as graphics or layout files.The following list gives the qualifiers you can use to customize your resource values:
mcc
followed by the three-digit country code. You can optionally add the MNC using mnc
and the two- or three-digit network code (for example, mcc234-mnc20
or mcc310
).r
followed by the uppercase two-letter ISO 3166-1-alpha-2 language code (for example, en
, en-rUS
, or en-rGB
).sw<dimension value>dp
(for example, sw600dp
, sw320dp
, or sw720dp
). This is generally used when providing multiple layouts, where the value specified should be the smallest screen width that your layout requires in order to render correctly. Where you supply multiple directories with different smallest screen width qualifiers, Android selects the largest value that doesn’t exceed the smallest dimension available on the device. The -sw600dp
configuration qualifier lets you provide resources only when a device is above a certain size. The sw stands for smallest width, but refers to the screen’s smallest dimension, and thus is independent of the device’s current orientation. With a -sw600dp
qualifier, you are saying, Use this resource on any device whose smallest dimension is 600dp or greater. This is a good rule of thumb for specifying a tablet-sized screen.w<dimension value>dp
(for example, w600dp
, w320dp
, or w720dp
). Also used to supply multiple layouts alternatives, but unlike smallest screen width, the available screen width changes to reflect the current screen width when the device orientation changes. Android selects the largest value that doesn’t exceed the currently available screen width. For example, -w600dp
will match any device where the current available screen width is 600dp or more, meaning a device may match when in landscape mode but not in portrait mode.Available Screen Height
. The minimum screen height required to use the contained resources, specified in the form h<dimension value>dp
(for example, h720dp
, h480dp
, or h1280dp
). Like available screen width, the available screen height changes when the device orientation changes to reflect the current screen height. Android selects the largest value that doesn’t exceed the currently available screen height. For example, a 640dp x 480dp screen has a height of 640dp when in portrait and 480dp when in landscape.long
or notlong
for resources designed specifi cally for wide screen. For example, WVGA is long; QVGA is notlong.portrait
), land (landscape
), or square (square
).car
or desk
. Introduced in API level 8.night
(night mode) or notnight
(day mode). Introduced in API level 8. Used in combination with the dock mode qualifier, this provides a simple way to change the theme and/or color scheme of an application to make it more suitable for use at night in a car dock.ldpi
, mdpi
, hdpi
, or xhdpi
to specify low (120 dpi), medium (160 dpi), high (240 dpi), or extra high (320 dpi) pixel density assets, respectively. You can specify nodpi
for bitmap resources you don’t want scaled to support an exact screen density. To better support applications targeting televisions running Android, you can also use the tvdpi
qualifier for assets of approximately 213dpi. This is generally unnecessary for most applications, where including medium- and high-resolution assets is suffi cient for a good user experience. Unlike with other resource types, Android does not require an exact match to select a resource. When selecting the appropriate folder, it chooses the nearest match to the device’s pixel density and scales the resulting Drawables accordingly.notouch
, stylus
, or finger
, allowing you to provide layouts or dimensions optimized for the style of touchscreen input available on the host device.keysexposed
, keyshidden
, or keyssoft
.nokeys
, qwerty
, or 12key
.navexposed
or navhidden
.nonav
, dpad
, trackball
, or wheel
.v7
). Used for resources restricted to devices running at the specified API level or higher.You can specify multiple qualifiers for a single set of resources, separated by dashes. For example, drawable-en-sw600dp-land
applies to English tablets in landscape orientation. Note that if you use multiple qualifiers for a resource directory, you must add them to the directory name in the certain order. See the official docs for the complete set of qualifiers available.
Details for Screen Pixel Density qualifiers
Before continue, read about Android screen densities. You'll know about difference between DPI and DP.
Imagery (drawable) assets use a different resource qualifier folder naming schema, under the /res/drawable folder, and use the -ldpi
and -hdpi
naming extensions, instead of those -small
and -large
naming extensions that the layout folder resource qualifier naming schema utilizes.
For example, one best practice is to ensure that all images are provided for multiple screen densities.
Density Classes
Density | DPI | Example Device | Scale | Pixels |
---|---|---|---|---|
ldpi | 120 | Galaxy Y | 0.75x | 1dp = 0.75px |
mdpi | 160 | Galaxy Tab | 1.0x | 1dp = 1px |
hdpi | 240 | Galaxy S II | 1.5x | 1dp = 1.5px |
xhdpi | 320 | Nexus 4 | 2.0x | 1dp = 2px |
xxhdpi | 480 | Nexus 5 | 3.0x | 1dp = 3px |
xxxhdpi | 640 | Nexus 6 | 4.0x | 1dp = 4px |
What do all these letters and numbers mean to you? A given image will appear larger on a screen with a lower density and smaller on a screen with a higher density. If you take a piece of paper and draw a vertical line and a horizontal line, splitting it into four pieces, a single piece (pixel) will take up a quarter of the paper. If you divide each of those quarters into four pieces, then a single piece (pixel) is one fourth of the size that it was. The pixel appears physically smaller even though the total size of the paper (the screen) has not changed.
Fortunately, Android makes handling this easy for you. Instead of specifying dimensions in raw pixels, you will use either density-independent pixels (referred to as dip or dp) or scale-independent pixels (sip or sp). Density-independent pixels are based on MDPI, so 1dp is 1px at medium density. The difference between one sp and one dp is that sp takes into account the user’s preferred font size. Therefore, all font sizes should be specified in sp and all other dimensions should be in dp.
You can find DPI for different devices at dpi.lv.
Screen Size Classes
Class | Size in dp | Layout Folder | Examples |
---|---|---|---|
small | 426x320 dp | layout-small | typical phone screen (240x320 ldpi, 320x480 mdpi, etc.) |
normal | 470x320 dp | layout-normal OR layout | typical phone screen (480x800 hdpi) |
large | 640x480 dp | layout-large | tweener tablet like the Streak (480x800 mdpi), 7" tablet (600x1024 mdpi) |
xlarge | 960x720 dp | layout-xlarge | 10" tablet (720x1280 mdpi, 800x1280 mdpi, etc.) |
This means that if you generate a 100x100 for mdpi
(1x baseline), then you should generate the same resource in 150x150 for hdpi
(1.5x), 200x200 image for xhdpi
devices (2.0x), 300x300 image for xxhdpi
(3.0x) and a 75x75 image for ldpi
devices (0.75x).
This is achieved by having res/drawable-hdpi, res/drawable-xhdpi, and res/drawable-xxhdpi folders with different versions of the same image. The correct resource is then selected automatically by the system based on the device density.
If you are developing for Android 3.2 and earlier and don’t need a precise DIP screen resolution control qualifier you can utilize the /res/layout-small resource qualifier for your small screen layouts and the /res/layout-large resource qualifier for your large screen layouts. There’s also a /res/layout-xlarge resource qualifier folder name that you can use, for extra large screen UI layouts, for instance on iTV sets, large tablets, PCs, netbooks, or notebooks.
If you wanted to specify a portrait UI layout for any of these non-normal-size resource qualifier names, you would then add -port
to the end of your folder name. Thus, if you had a small screen portrait UI design, you would have that design in a specially named /res/layout-small-port folder. It is important to note that the -port
must always come after the size modifier.
If you wanted to specify landscape UI layouts for any of these non-normal−sized resource qualifier names, you would then add -land
to the end of your folder name. Thus if you had a large screen landscape UI design, you would have that design in a specially named /res/layout-large-land folder. It is important to note that the -land
must always come after the size modifier.
Normal, also known as medium-sized screen layout designs, do not require a resource qualifier. These UI designs would be kept in the root UI layout folder, or the /res/layout folder, and this "primary" or default UI design would also define the name use for the other files in the other folders.
Sometimes it's a good idea to create image with grid and check view zone on all available devices. For this you can use proportion calculator and gradient maker with steps.
Useful for designer
Following is a list of resources for different devices' density (in pixels).
ldpi | mdpi | hdpi | xhdpi | xxhdpi | xxxhdpi | |
---|---|---|---|---|---|---|
Launcher And Home | 36*36 | 48*48 | 72*72 | 96*96 | 144*144 | 192*192 |
Toolbar And Tab | 24*24 | 32*32 | 48*48 | 64*64 | 96*96 | 128*128 |
Notification | 18*18 | 24*24 | 36*36 | 48*48 | 72*72 | 96*96 |
Background | 240*320 | 320*480 | 480*800 | 768*1280 | 1080 *1920 | 1440*2560 |
Details for Smallest Width, Available Width, Available Height qualifiers
Android 3.2 changed how screen size resource qualifiers were defined, by adding three different DIP size based resource qualifiers: SmallestWidth, which is written as -sw###dp
, or -sw480dp
, for instance, AvailableWidth, as indicated using a -w###dp
, or -w600dp
for instance, and AvailableHeight, as indicated using a -h###dp
, or -h720dp
for instance.
What these do is to give the developer a much finer numeric control over a given UI design to screen characteristics pairing. With the small
, medium
, large
, and xlarge
resource qualifiers, developers had to rely on Android to determine what screen resolutions qualify for these general categories. A screen size specific resource qualifier allows for a pixel-precision value to be set by the developer, so there is zero guesswork as to what design will be used with any given physical screen resolution characteristics.
The SmallestWidth or -sw
modifier looks at the smallest possible dimension of the screen, regardless of its orientation, which makes it significantly different from an AvailableWidth or -w
modifier, which will change numeric value evaluation within the OS every time that a user changes their device orientation. The same goes for the AvailableHeight, or -h
modifier.
SmallestWidth is used to determine whether enough DIP width is available for your UI design regardless of the orientation of the device. The most common dimension for an Android screen is 480 pixels, which is -sw480dp
and is found in devices with 320x480, 480x800, and 480x854 resolution screens. The next most common is 800 pixels, common in 480x800 and 800x1280 screen size devices, such as smartphones and tablets.
Now that smartwatches such as the Samsung Galaxy Gear are becoming popular, 320 pixel devices like a 320x320 Galaxy Gear or 320x480 entry-level touchscreen smartphone will also become a popular resolution, so a -sw320dp
, -sw480dp
, and -sw800dp
qualifier will also be used quite frequently by Android developers.
Some popular resolutions have only one resolution out there, such as the 1024x600 netbook resolutions, which use a -sw600dp
qualifier, and the Pseudo HD 1280x720 resolution, which uses a -sw720dp
qualifier.
It is important to note that the SmallestWidth calculation algorithm that is implemented by the Android OS takes into account any system chrome, that is, any Android OS UI elements such as status bars and bottom mounted virtual control button bars. This means the SmallestWidth algorithm won’t match the physical screen resolution, but rather the available resolution that can be used to contain your parent UI ViewGroup layout container.
The SmallestWidth -sw###dp
qualifier can be used in conjunction with a -port
and a -land
qualifier, such as /res/layout-sw480dp-land to allow developer control over UI design for any screen size and orientation. This allows a developer precise control over not only how their UI fits any device, but also over how digital image or digital video content is displayed.
The other two -w###dp
and -h###dp
resource qualifiers re-evaluate for any orientation change for a user’s Android device, so the resource qualifiers can be used to replace Java code that detects device orientation changes, and then implements a different UI design or even content design paradigm.
Since these -w###dp
and -h###dp
qualifiers can be used to determine one screen axis resolution, and since this changes with device orientation, you could use them with a -port
and -land
qualifier to match any popular resolution.
For instance -w480dp
on its own would call both a 320x480
resolution entry level smartphone, when it is in landscape orientation, and also an 480x800 or 854x480 smartphone or tablet when it’s in portrait orientation. To also control which of these device scenarios you are matching your UI design to you can add -port
and -land
, so to fit a 320x480 entry-level (inexpensive) smartphone use -w320dp-port
and use -w480dp-port
to fit 800x480 or 854x480 smartphones or tablets when they are being used in portrait mode. It would be cool to be able to use these two together to specify a complete display screen resolution, but because they are in the same category this can’t be done currently. Luckily, it is just as effective, that is, you can achieve the same result, by using the size and orientation qualifiers together.
Following table shows some of the different types of Android devices and the DIP (or DP) screen size ranges, typical resolution and smallest width normally associated with each type of device.
It is also possible to restrict your applications to only run on devices that support certain screen size, density, and resolution characteristics. This is done by using an "analog" or equivalent of the resource qualifier that you just learned about (Smallest Width). This XML parameter is used inside the <supports-screens>
tag, which is a child tag of your parent <manifest>
tag for your application manifest.
The parameter is the android:requiresSmallestWidthDp
parameter, which does the same thing as the -sw###dp
resource qualifier, so it looks at the smaller of the two X:Y or W:H screen dimensions, and uses the tag format:
<supports-screens android:requiresSmallestWidthDp="720" />
Determining configuration at runtime
When the app is running, we can always check the current configuration (orientation, screen size, etc) by accessing the Configuration
object through getResources().getConfiguration()
within an activity or context object. For example, to determine the orientation (portrait or landscape) inside an activity, we can do:
String image; int orientation = getResources().getConfiguration().orientation; if (orientation == Configuration.ORIENTATION_PORTRAIT) { image = "image_portrait.png"; } else if (orientation == Configuration.ORIENTATION_LANDSCAPE) { image = "image_landscape.png"; }
We can similarly access this within any object by getting access to a Context
object. For example, within an ArrayAdapter
by using getContext().getResources().getConfiguration()
to access the configurations.
You can get screen size in dp with following
DisplayMetrics displayMetrics; displayMetrics = new DisplayMetrics(); WindowManager windowManager = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE); windowManager.getDefaultDisplay().getMetrics(displayMetrics); int height = Math.round(displayMetrics.heightPixels / displayMetrics.density); int width = Math.round(displayMetrics.widthPixels / displayMetrics.density); Log.d(TAG, width + "x" + height);
Layout aliases
There is one final concept to discuss when creating universal application UIs, and that is layout aliases. Often the same layout should be used for multiple device configurations, but chaining multiple resource qualifiers together (such as a smallest width qualifier and a traditional size qualifier) on the same resource directory can be problematic. This can often lead developers to create multiple copies of the same layout in different directories, which is a maintenance nightmare.
We can solve this problem with aliasing. By creating a single layout file in the default resource directory, we can create multiple aliases to that single file in resource-qualified values directories for each configuration that uses the layout. The following snippet illustrates an alias to the res/layout/main_tablet.xml file:
<resources> <item name="main" type="layout">@layout/main_tablet</item> </resources>
The name
attribute represents the aliased name, which is the resource this alias is meant to represent in the selected configuration. This alias links the main_tablet.xml file to be used when R.layout.main
is requested in code. This code could be placed into res/values-xlarge/layout.xml and res/values-sw720dp/layout.xml, and both configurations would link to the same layout.
Useful links