To make the great Application, the great code is not enough because the users interact with the visual part not a code. Everything except the code is called Resources
there are many kind of resources
such as text, image, animation, etc. In this article you will learn about the resource types and how to use them in your application.
When the resources
are another part of the application, you need to know about the basic of application development and UI creation.
In the article we will learn by apply the resources
to the existing Code/UI. I have provide the Base Project for use to learn this article you can download it from the link below.
The Resources
is everything of the application except the Java code. On Android Platform there are many kind of Resources
such as text, color, layout, dimension, etc. Android provides the specific folders the specific resources type, the root folder of resources is res/
and this folder contains many sub folder for each resource type.
The resources and their folder Directory | Resource in Directory |
animator | The Property Animations in XML file format |
anim | The View Animations in XML file format |
color | The Color State List Resource in XML file format |
drawable | Image files or XML file |
layout | UI layout files in XML file format |
menu | Menu definition file in XML file formal |
raw | Everything else that you need to use in the application |
value | Simple values such as text, dimensions, color, etc. |
xml | Another XML file that you want to use in the application such as config file. |
The Layout resource
is the file that is a definition of User Interface, you have learned this resource type from the past article (Contest Article #4). The directory that store the layout resources is res/layout
.
This is an example of layout
file
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="me.vable.android.androidresourceslessons.ValuesExampleActivity"
android:orientation="vertical"
>
<TextView
android:text="What is your name?"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="textPersonName"
android:singleLine="true"
android:maxLines="1"
android:hint="Name"
/>
<TextView
android:text="How do you feel today?"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp"/>
<RadioGroup
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<RadioButton
android:text="Great :)"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioButton
android:text="Upset :("
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<RadioButton
android:text="Tearful :'("
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="false"
/>
</RadioGroup>
</LinearLayout>
The Value Resource
is the XML that contain a definition of basic value, such as string
, color
, and dimension
. This resource type is store in a folder res/value
, you can create the resource files and name it as you want all value resources can place in a one XML file but not recommended.
To create the value resource, right-click on the res/value folder and select New > Values resource file.
Then, enter the resource name.
There is no official naming convention for resource files, but I recommend you to name it as <resource_type>_<activity or fragment>_<activity or fragment name>.xml.
For example: I have the Activity name MainActivity
, I will create the string value resource
for this Activity the name of resource file should be string_activity_main.xml
The String resources provide the text that you can use in both Java code and UI layout.
This is an example of String resources
file
<resources>
<string name="app_name">AndroidResourcesLessons</string>
<string name="hello_world">Hello world!</string>
<string name="action_settings">Settings</string>
</resource>
In this file there are String resources with name app_name, hello_world, and action_settings. You can use these String resources in the layout enter a text "@string/"
and follow by the id of the resource that you want.
<TextView
android:text="@string/hello_world"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp" />
And in the Java you can refer to the String by using the R class instance such as R.string.app_name
TextView helloWorldTextView = (TextView) findViewById(R.id.textview_hello_world);
helloWorldTextView.setText(R.string.hello_world);
Naming Convention
No official String resource
name naming convention right now, but I reccommend you to the pattern <layout>_<view id>
such as activity_main_textview_title to specific the view that use this String or if this String is a common sentence you can also use just name such ok
, error_no_connection
.
Now, Open the layout activity_values_example.xml
and try to convert all hard code String to String Resource reference.
Note: Please create a new String Resources file with name string_activity_value_example.xml
.
Note: Some character can not use in String Resource file you need to replace it with the escape code.
When you want to change the color of text in the Layout
file, you can use the hard code string of color
code but many time you use the same color for many element. When you want to change the color you need to find each element that use this color, so that waste your time.
The Color resource
is the answer, you only define the color that you want to use and then refer this resource in any place that you want to use this color.
You can use the same Color resources
file for whole application, because the whole app should use the same colors, same style for making the experience consistent. The common Color resources file name is colors.xml
.
This is an example of Color resources
.
="1.0"="utf-8"
<resources>
<color name="text_dark">#252525</color>
<color name="text_light">#DEDEDE</color>
<color name="text_warn">#FF0000</color>
</resources>
From the XML there are 2 color resources text_dark and text_light, to use them in layout, you just enter the reference "@color/
" follow by the Color resource
name.
<TextView
android:text="@string/hello_world"
android:textColor="@color/text_warn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18dp" />
You can refer the color resurce by using R.color.<color resource name>
e.g. R.color.text_warn
.
TextView helloWorldTextView = (TextView) findViewById(R.id.textview_hello_world);
helloWorldTextView.setText(R.string.hello_world);
helloWorldTextView.setTextColor(R.color.text_warn);
Naming Convention
No official Color resource
name naming convention right now, but you can use the name that meaningful and indicate its role of the resource such as text_warn
is mean color of warning text.
Now, Open the layout activity_values_example.xml
and try to color the text or Views that you want.
To size and position the View
you can use a hard code value in dp, sp, px units. Same as the Color resources
, sometime you want to use same value with many element e.g. the element's margin and padding, you should to make it as resource.
Like the Color you can store the common dimension values
in the one file except you want to create a very specific value e.g. set the margin to only one element. The common Dimension resources file name is dimens.xml.
<resources>
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<dimen name="default_margin">8dp</dimen>
</resources>
To use the dimension resource
in the layout file, you just refer it by using @dimen/<dimesion resource name>.
<TextView
android:text="@string/hello_world"
android:textColor="@color/text_warn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin"
android:textSize="18dp" />
In the java code you can use R.dimens.<dimesion resource name>
to refer the specific dimension resource.
getResources().getDimension(R.dimen.default_margin);
getResources().getDimension()
method will return the value in pixel unit.
Naming Convention
No official Dimension resource name naming convention right now, but you can use the name that meaningful and indicate the role of the resource such as default_padding.
Now, Open the layout activity_values_example.xml and try to make the space between the questions.
You can make the array of String
as a resource
too. This type of resource should be use for provide a static series of data such as using as Data source for Spinner.
You can place the String array
in the same file with String resource.
This is an example of String Array resources.
<string-array name="string_activity_value_example_spinner_color_options">
<item>Red</item>
<item>Yellow</item>
<item>Blue</item>
</string-array>
The example is the String Array
for color spinner
, you can use it in java code by using R.array.<string array resource name>
.
I will use it as the Spinner Adapter
data source, Here is my layout:
<Spinner
android:id="@+id/spinner_color"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
And this is old Java code:
String[] colors = new String[]{"Red","Yellow","Blue"};
Spinner colorSpinner = (Spinner)findViewById(R.id.spinner_color);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, colors);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
colorSpinner.setAdapter(adapter);
Then, I replace a String[] hard code with getResources().getStringArray() method.
String[] colors = getResources().getStringArray(R.array.string_activity_value_example_spinner_color_options);
Spinner colorSpinner = (Spinner)findViewById(R.id.spinner_color);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, colors);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
colorSpinner.setAdapter(adapter);
Here is a result:
The result is same as the hard code String array
.
Naming Convention
No official String Array resource
name naming convention right now, but I recommend you to the pattern <layout>_<view id>
such as activity_main_color_options
to specific the view that use this String Array
.
Drawable resource
is refer to a graphic file that can draw on the screen. Drawable resources
can split in to two groups the first is the real image file (.png, .jpg, .gif) and 9-patch file, and the another group is XML definition file such as XML Bitmap, Layer List, etc.
The real image file (.png, .jpg, .gif) , you can place any image file in the drawable
directory directly and then you can reference it by using the id e.g. R.drawable.<file name without extension>
in the Java code, and @drawable/<file name without extension>
in the layout file.
For example: I place the png file name "ic_error.png" , then I can use it as src of ImageView
<ImageView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:src="@drawable/ic_error" />
And in the java code I can get this drawable by using the getResources().getDrawable()
method.
Drawable drawable = getResources().getDrawable(R.drawable.ic_error);
Or set it ti ImageView source directly
ImageView errorImageView = (ImageView) findViewById(R.id.imageview_error);
errorImageView .setImageResource(R.drawable.ic_error);
Nine Patch
is a PNG image + area mark, Nine Patch allow Android to stretch when the content it bigger than image. Nine Patch
is generally used for make a View background
image.
From the picture above, you will see that when you set the TextView
's background
to normal bitmap file when the content is overflow the background
image will misshapen but this problem not occurs when you use a 9-patch.
On the 9-patched png
there are 1 pixel extra from each border for using to mark the area the can stretch and content area. The top and left marks are used to defines the stretchable area while the bottom and right marks are used to defines the padding box or content area (if no mark, content will can fit the background).
Android provides a tool for create the nine patch image called draw9patch
you can found it at <android_sdk_path>/tools/
Let's try to build the nine patch, save the picture below.
Then open the draw9patch and drag the image file to the draw9patch window
Drag the horizontal line and vertical line at each border to create the patch
Check all options and see the preview on the right of window
Now, save the 9-patched image
and add it the project. Open the file activity_drawable_example.xml and try to change the buttons background to the 9-patched file.
Note: You can edit the patch in Android studio by double click on the 9-patch file
Android provides a menu resource
for using to create the menu. On Android 3.0+ the Options Menu is show on the app's ActionBar
and there are 2 kind of options menu that are Action Menu
and Popup Menu
but on the older device there is a menu button on the hardware and when you click it the menu will show on the bottom of the screen. However, there are developers that create the library to bring the ActionBar to the legacy device that library called ActionBarSherlock
and now Google bring the ActionBar
to the legacy device via the library AppConpat
.
To create the options menu
, you need to create a menu resource
in res/menu
.
In the base project I have provided you a MenuExampleActivity with menu_example.xml as a menu resource. Let's try to create the menu now!!
Here is our current menu resource XML code
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="me.vable.android.androidresourceslessons.MenuExampleActivity" >
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="never" />
</menu>
There is a Settings menu in the resource file, when you run the app you will see the menu like this.
These are the important attributes of options menu
- android:id - The id of this menu, without the id you will can access the menu in Java code.
- android:title - The text that you want to show on this menu.
- android:orderInCategory - The order of this menu in its
category
. - android:icon - The icon of this menu, will show when the menu is an
Action Menu
and always show on the old style menu
(legacy Android). - app:showAsAction / android:showAsAction - Is this menu an
Action Menu
, you can set it to always show as Action Menu, or depends on the Action Bar
space, or never show as Action Menu.
Note: If your Activity was extended from the ActionBarActivitiy
in AppCompat
library you need to import an app namespace xmlns:app="http://schemas.android.com/apk/res-auto"
and use the showAsAction proper from app
namespace. Or you can add both app:showAsAction and android:showAsAction for make sure that the Action Menu
will show.
I suggest you to name the id of menu
as action_<name> if it's an Action Menu
or menu_<name> if it's a normal Menu
.
Now, I want to create the about menu as a popup menu.
<item android:id="@+id/menu_about"
android:title="About"
android:orderInCategory="101"
app:showAsAction="never"
/>
I set the new menu showAsAction attribute to never because I don’t want to show as the ActionMenu
Here is the result:
Next, I will create a Refresh Action Menu.
<item android:id="@+id/action_refresh"
android:title="Refresh"
android:orderInCategory="1"
app:showAsAction="always"
/>
This Menu will always show as the Action Menu on the Action Bar.
If you not provides the icon for Action Menu it will show the title text instead. Try to add the icon to Refresh Action Menu now.
When you create an Action Menu
you should to add the menu icon
. Android suggest to use the monochrome image as the menu icon, you must to create the image that simple and has a clear meaning and well known.
I decide to use this icon for the refresh menu. Android Studio provides the Image Asset import wizard that help the developer to convert the image into the proper size and color. To use the wizard, right click on the res
folder then select New > Image Asset.
You will see the wizard window
There are 3 drawable asset types that you can use this wizard to import, there are Launcher Icons, Action Bar and Tabs Icons, and Notification Icon.
We will use the Action Bar and Tab Icons option for importing the menu icon.
These are description of the options.
- Asset Type - Type of
asset
that you want to create - Foreground - You can use your own image, or using the clipart, or text.
- Image File - If you use your own image, the wizard will let you select the image.
- Clipart - If you set foreground to clipart, the wizard will let you choose the clipart.
- Text - If you set foreground to text, you can enter you text here.
- Font - Set the font of text.
- Trim surrounding blank space - trim the space around the foreground element.
- Additional padding - add the space around the foreground element.
- Theme - You app's theme, if you choose a custom options it will let you choose that color of icon.
- Resource name - Set the name of this asset.
Note: Resource name should be name as ic_action_<name>
After selected the options, click the next button and you will see the outputs preview.
I can't see my image because it color is white Select the Target Module to you app, and select the res directory of you app.
Now, I have a drawable resource
name ic_action_refresh. Add it to the menu
!!
Collapse | Copy Code
<item android:id="@+id/action_refresh"
android:title="Refresh"
android:orderInCategory="1"
app:showAsAction="always"
android:icon="@drawable/ic_action_refresh"
/>
Here is a result:
Next, we will access the options menu
in Java code and write the code to react the options menu
click event.
Open the Activity
file you will see the onCreateOptionsMenu()
and onOptionsItemSelected()
method (create it if not exist)
Collapse | Copy Code
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_example, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
onCreateOptionsMenu()
method is used to inflate the options menu
to show on the View
.
onOptionsItemSelected()
method is used to detect the Click event on the menu
.
Now, we focus on the onOptionsItemSelected()
method and I will show the Toast
message for each menu.
Collapse | Copy Code
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
Toast.makeText(this,"Settings menu was clicked",Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.menu_about) {
Toast.makeText(this,"About menu was clicked",Toast.LENGTH_SHORT).show();
return true;
}
else if (id == R.id.action_refresh) {
Toast.makeText(this,"Refresh menu was clicked",Toast.LENGTH_SHORT).show();
return true;
}
return super.onOptionsItemSelected(item);
}
And run the app!!
In the res/
folder you will see that there are some folder that has a same name with a suffix such as drawable, drawable-xhdpi, drawable-mdpi. That is an alternative resources
that is used to provide to the specific device such as the device with large screen, the device that run Android 4.4+, etc.
Android provide the resource qualifiers
for use to specific that the resource folder is used to provide to the specific device or state.
To create the alternative resources
directory, right click on the res/
folder then select New > Android resource directory
You will see the New Resource Directory window, you can select the resource type that you want to create an alternative resources directory
.
There is a lot of qualifier
for resources
that you can use to create an Alternative Resource Directory
. E.g. If yhou want to localize your, app you need to use the Region option. If you want to create the UI fot tablet, you need to use the Screen Size option.
I will show you an example of String alternative resources
for the landscape
orientation. Select the resource type as values and select the orientation and click the >> button
Set the Screen orientation to Landscape, then then click OK button.
You will see the values-land in res folder
Try to using the alternative resources
now!! In the base project I have created the AlternativeResourcesExampleActivity
and its layout file activity_alternative_resources_example.xml
. Now, look at the layout file. There is a Greeting TextView.
We will serve the different String resource for the Greeting TextView inlandscapr mode and portrait mode.
First, create the String resource name textview_greeting
with the value "Hello, John" in the strings.xml file
<string name="textview_greeting">Hello, John</string>
Second, create the strings.xml
resource file in an folder values-land
and put the String resource name textview_greeting
with the value "Good morning, John".
<string name="textview_greeting">Good morning, John</string>
Finally, set the text of Greeting TextView
to String resource textview_greeting
.
<TextView
android:text="@string/textview_greeting"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
Run the app and try to rotate the device.
In the res/
folder you will see the drawable-xxxx folders, they are an Alternative Drawable Resources
for the specific screen density.
The picture above show the comparison of image size in each screen density. The mdpi
density is the baseline size where a 1 pixel is equals to a 1 dp.
Density
| DPI
| Example Device
| Scale
| Pixels/dp
|
ldpi
| ~120
| Samsung Galaxy Y (~133)
| 0.75x
| 1px = 0.75dp
|
mdpi
| ~160
| HTC Wildfire S (~180)
| 1.0x
| 1px = 1dp
|
hdpi
| ~240
| Nexus One (~252)
| 1.5x
| 1px = 1.5dp
|
xhdpi
| ~320
| Nexus 4 (~318 dpi)
| 2.0x
| 1px = 2dp
|
xxhdpi
| ~480
| Nexus 5 (~445 dpi)
| 3.0x
| 1px = 3dp
|
xxhdpi
| ~640
| -
| 4.0x
| 1px = 4dp
|
The table show the relation of density, dpi, scale, pixel per dp, and the example device, you will see that the device density in not only depends on the dpi but it also depends on the manufacturer.
Look at the AlternativeDrawableExampleActivity
there are many ImageViews that consume the image resource
from different drawable
folder. (I have put the images that have same size 128px*128px in all folder with different name)
Try to run it now.
You will see that the images that display on your device screen have a different size, because Android will scale down or up the image in each folder to the proper size.
If you place the images in the folder that has higher density than your device screen, Android will scale down them.
On the other hand Android will scale up the images in the folder that has lower density than your device screen.
Note: In the picture I run the application on Nexus 5.
Note: drawable and drawable-mdpi
resources will have a same size.
When Android scale down the Images, it will consumes the processor/memory resource. Thus you should to provide all sizes of image if possible.
Now, look at the AlternativeDrawableExample2Activity
. I have put the images into the folders drawable-ldpi
, drawable-mdpi
, drawable-hdpi
, and drawable-xhdpi
but in this example I resize each image to the proper size by use the multiply factor in the table above and rename it as different name.
Try to run it now.
Wow!! Android scale it to the same size and display on the screen automagically.
Another example, the AlternativeDrawableExample3Activity, this activity has only one ImageVIew
with set the src
to the drawable resource
. I have put the scaled (proper size) image into the folders drawable-ldpi
, drawable-mdpi
, drawable-hdpi
, and drawable-xhdpi
. All of the image name are same.
When there are the same resource
name in many resource
folder Android will choose the proper resource on by consider the resource qualifiers. Thus is the reason why you should to scale the image resource yourself.
Sometimes you want to add some addition graphic on the high density display only you will can do it by provide the different image for each resource folder but all of images use the same resource name.
Now, on the Android Studio open the design view of activity_alternative_drawable_example3.xml
then click the preview device button and select Preview All Screen Size
This screen will preview the size of a screen elements on many device, you can use this tool to check you layouts and resources.
I recommends you to design the image files for XHDPI or XXHDPI density becauseyou can scale down the images without losing the quality.
I would like to recommend the tool for resizing image to XHDPI, HDPI, MDPI, and LDPI that tool is Android Resizer Tool you can download it from the xda-developers thread.
How to use it?
Open the tool.
Enter number 2 to config it
Enter the source images density recommend to use XHDPI (enter 1)
Enter the outputs DPI 1, 2, 3, and 4. Then enter the source images folder.
Enter the outputs images folder
Enter number 1 for convert the images.
Finish!!
This is an output folder.
Another tool that I would like to recommend is Android Asset Studio it is an online tool for creating theme, icon, etc.
Finish!! now you have learned about Android Resources
type, there are many Resources
that I haven't said in this article, please try it yourself. Remember that the only way to success is practice, practice, practice, practice, and more practice. Goodluck!!
The resources
is very important to create the great application that you need to tke care it because the user has interaction with the visual part of an application not a code. After learned this article, please try to learn the other resources type to complete the jigsaw of the great application. Hope you enjoy your Android Developer Life!!
24/08/2014 initial submit
24/08/2014 fix the inner link
25/08/2014 add Alternative Drawable Resources Examples
25/08/2014 add more explaination