Skip to content

04 - Android Resources

All in some /res subdirectory

  • ./anim – Animations
  • ./color – Colors and Color State lists
  • ./drawable – Picures (binary and xml)
  • ./layout – Layouts
  • ./menu – Menus
  • ./mipmap – launcher icons only
  • ./raw – Misc files (audio, video, etc)
  • ./values – texts, sizes, styles
  • ./xml – xml files
  • ...

Animation

  • Property animation
    • Modify objects property values over a time with an Animator
  • View animation
    • Tween animation – series on transformations on single image with Animation
    • Frame animation – sequence of images with AnimationDrawable

Color

  • File location res/color/filename.xml
  • Resource reference R.color.filename
  • Android:color
    • The value always begins with a hash (#) character and then followed by the Alpha-Red-Green-Blue information in one of the following formats:
    • #RGB
    • #ARGB
    • #RRGGBB
    • #AARRGGBB
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item 
        android:color="hex_color" 
        android:state_pressed=["true" | "false"]
        android:state_focused=["true" | "false"] 
        android:state_selected=["true" | "false"]
        android:state_checkable=["true" | "false"] 
        android:state_checked=["true" | "false"]
        android:state_enabled=["true" | "false"] 
        android:state_window_focused=["true" | "false"] />
</selector>

res/color/button_text.xml

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:color="#ffff0000" 
        android:state_pressed="true" /> <!-- pressed -->
    <item android:color="#ff0000ff" 
        android:state_focused="true" /> <!-- focused -->
    <item android:color="#ff000000" /> <!-- default -->
</selector>
1
2
3
4
5
<Button 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/button_text"
    android:textColor="@color/button_text" /> 

Drawable

  • Graphics that can be drawn
    • Retrieve with APIs such as getDrawable(…)
    • Apply to other XML using android:drawable and android:icon
  • BitmapDrawable – .png, .jpg, .gif
  • NinePatchDrawable - .9.png – PNG with stretchable regions
  • Layer List – array of other Drawables. Drawn in order, largest index on top
  • State List – differen bitmap graphics for different states (dif image when button is pressed)
  • Transition Drawable – can crossfade between two drawables
  • Inset, Clip, Scale, Shape….

Bitmap

  • .png preferred, .jpg acceptable, .gif discouraged
  • File location
    /res/drawable/filename.png
  • XML bitmap
    /res/drawable/filename.xml
  • Nine-patch
    • PNG image in which you can define stretchable regions
    • Usually background of a View that has at least one dimension set to "wrap_content"

Configuration qualifiers

To ensure your resources look their best, you should include alternative versions for different screen possibilities.

  • ldpi (low)
  • mdpi (medium)
  • hdpi (high)
  • xhdpi extra-high)
  • xxhdpi (extra-extra-high)
  • xxxhdpi (extra-extra-extra-high)
  • nodpi (no scaling)
  • port (portrait)
  • land (landscape)
  • long (long aspect ratio)
  • notlong (normal aspect ratio)
  • small, normal, large, xlarge (screen size)

Folder name example:
res/layout-xlarge-land/my_layout.xml

Screen size and density

Size

  • xlarge screens are at least 960dp x 720dp
  • large screens are at least 640dp x 480dp
  • normal screens are at least 470dp x 320dp
  • small screens are at least 426dp x 320dp

Density

  • ldpi (low) ~120dpi
  • mdpi (medium) ~160dpi
  • hdpi (high) ~240dpi
  • xhdpi (extra-high) ~320dpi
  • xxhdpi (extra-extra-high) ~480dpi
  • xxxhdpi (extra-extra-extra-high) ~640dpi

layout

Layer list

  • Array of other drawables
  • Last drawable in top
  • /res/drawable/filename.xml

layout

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item>
        <bitmap 
            android:gravity="center" 
            android:src="@drawable/android_red" />
    </item>
    <item android:left="10dp" android:top="10dp">
        <bitmap 
            android:gravity="center" 
            android:src="@drawable/android_green" />
    </item>
    <item android:left="20dp" android:top="20dp">
        <bitmap 
            android:gravity="center" 
            android:src="@drawable/android_blue" />
    </item>
</layer-list> 
1
2
3
4
<ImageView  
    android:layout_height="wrap_content"  
    android:layout_width="wrap_content"  
    android:src="@drawable/layers" /> 

State list

Different images to represent the same graphic, depending on the state of the object
/res/drawable/filename.xml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android" 
    android:constantSize=["true" | "false"]  
    android:dither=["true" | "false"]  
    android:variablePadding=["true" | "false"] >  
    <item 
        android:drawable="@[package:]drawable/drawable_resource" 
        android:state_pressed=["true" | "false"]    
        android:state_focused=["true" | "false"]    
        android:state_hovered=["true" | "false"]    
        android:state_selected=["true" | "false"]    
        android:state_checkable=["true" | "false"]    
        android:state_checked=["true" | "false"]    
        android:state_enabled=["true" | "false"]    
        android:state_activated=["true" | "false"]    
        android:state_window_focused=["true" | "false"] />
</selector> 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_pressed" 
        android:state_pressed="true" /> <!-- pressed -->
    <item android:drawable="@drawable/button_focused" 
        android:state_focused="true" /> <!-- focused -->
    <item android:drawable="@drawable/button_focused" 
        android:state_hovered="true" /> <!-- hovered -->
    <item android:drawable="@drawable/button_normal" /> <!-- default -->
</selector> 
1
2
3
4
<Button  
    android:layout_height="wrap_content"  
    android:layout_width="wrap_content"  
    android:background="@drawable/button" /> 

Transition

Can cross-fade between the two drawable resources.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android" >  
    <item 
    android:bottom="dimension" 
    android:drawable="@[package:]drawable/drawable_resource" 
    android:id="@[+][package:]id/resource_name" 
    android:left="dimension" 
    android:right="dimension" 
    android:top="dimension" />
</transition> 
1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<transition xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/on" />
    <item android:drawable="@drawable/off" />
</transition> 
1
2
3
4
5
<ImageButton 
    android:id="@+id/button" 
    android:layout_height="wrap_content" 
    android:layout_width="wrap_content" 
    android:src="@drawable/transition" /> 
1
2
3
4
ImageButton button = (ImageButton) findViewById(R.id.button);
TransitionDrawable drawable = (TransitionDrawable) 
button.getDrawable();
drawable.startTransition(500); 

Options Menu, Context Menu, or submenu

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
  <item android:id="@[+][package:]id/resource_name"
     android:title="string"
     android:titleCondensed="string"
     android:icon="@[package:]drawable/drawable_resource_name"
     android:onClick="method name"
     android:showAsAction=["ifRoom" | "never" | "withText" | "always" | "collapseActionView"]
     android:actionLayout="@[package:]layout/layout_resource_name"
     android:actionViewClass="class name"
     android:actionProviderClass="class name"
     android:alphabeticShortcut="string"
     android:numericShortcut="string"
     android:checkable=["true" | "false"]
     android:visible=["true" | "false"]
     android:enabled=["true" | "false"]
     android:menuCategory=["container" | "system" | "secondary" | "alternative"]
     android:orderInCategory="integer" />
  <group android:id="@[+][package:]id/resource name"
     android:checkableBehavior=["none" | "all" | "single"]
     android:visible=["true" | "false"]
     android:enabled=["true" | "false"]
     android:menuCategory=["container" | "system" | "secondary" | "alternative"]
     android:orderInCategory="integer" >
    <item />
  </group>
  <item >
    <menu>
     <item />
    </menu>
  </item>
</menu> 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@+id/item1"
        android:title="@string/item1"
        android:icon="@drawable/group_item1_icon"
        android:showAsAction="ifRoom|withText"/>
    <group android:id="@+id/group">
        <item android:id="@+id/group_item1"
            android:onClick="onGroupItemClick"
            android:title="@string/group_item1"
            android:icon="@drawable/group_item1_icon" />
        <item android:id="@+id/group_item2"
            android:onClick="onGroupItemClick"
            android:title="@string/group_item2"
            android:icon="@drawable/group_item2_icon" />
    </group>
    <item android:id="@+id/submenu"
    android:title="@string/submenu_title"
    android:showAsAction="ifRoom|withText" >
        <menu>
            <item android:id="@+id/submenu_item1"
            android:title="@string/submenu_item1" />
        </menu>
    </item>
</menu> 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
public boolean onCreateOptionsMenu(Menu menu) {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.example_menu, menu);
    return true;
}

public void onGroupItemClick(MenuItem item) {
    // One of the group items (using the onClick attribute) was clicked
    // The item parameter passed here indicates which item it is
    // All other menu item clicks are handled by onOptionsItemSelected()
} 

Values

Typed array

res/values/filename.xml

1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array
        name="array_name">
        <item>resource</item>
    </array>
</resources> 
1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <array name="icons">
        <item>@drawable/home</item>
        <item>@drawable/settings</item>
        <item>@drawable/logout</item>
    <array>
</resources>
1
2
3
Resources res = getResources();
TypedArray icons = res.obtainTypedArray(R.array.icons);
Drawable drawable = icons.getDrawable(0); 

Colors

  • res/values/colors.xml
  • R.color.color_name
  • The value always begins with a pound (#) character and then followed by the Alpha-Red-Green-Blue information in one of the following formats:
    • #RGB
    • #ARGB
    • #RRGGBB
    • #AARRGGBB
1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <color name="color_name">hex_color</color>
</resources> 
1
2
3
4
5
<?xml version="1.0" encoding="utf-8"?>
<resources>
   <color name="opaque_red">#f00</color>
   <color name="translucent_red">#80ff0000</color>
</resources> 
1
2
Resources res = getResources();
int color = res.getColor(R.color.opaque_red); 
1
2
3
4
5
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:textColor="@color/translucent_red"
    android:text="Hello"/> 

Dimensions

  • res/values/filename.xml
  • R.dimen.dimension_name
    • dp - Density-independent Pixels
    • sp - Scale-independent Pixels ( scaled by the user's font size preference)
    • pt - Points - 1/72 of an inch based on the physical size of the screen.
    • px - Pixels - Corresponds to actual pixels on the screen.
    • mm - Millimeters - Based on the physical size of the screen
    • in - Inches - Based on the physical size of the screen.
1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="dimension_name">dimension</dimen>
</resources> 
1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <dimen name="textview_height">25dp</dimen>
    <dimen name="textview_width">150dp</dimen>
    <dimen name="ball_radius">30dp</dimen>
    <dimen name="font_size">16sp</dimen>
</resources> 
1
2
Resources res = getResources();
float fontSize = res.getDimension(R.dimen.font_size); 
1
2
3
4
<TextView
    android:layout_height="@dimen/textview_height"
    android:layout_width="@dimen/textview_width"
    android:textSize="@dimen/font_size"/> 

Strings

  • res/values/filename.xml
  • R.string.string_name
1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="string_name">text_string</string>
</resources> 
1
2
3
4
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="hello">Hello!</string>
</resources> 
1
2
3
4
<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="@string/hello" /> 
1
String string = getString(R.string.hello); 

String array

  • res/values/filename.xml
  • R.array.string_array_name
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="string_array_name">
        <item>text_string</item>
    </string-array>
</resources> 
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="planets_array">
        <item>Mercury</item>
        <item>Venus</item>
        <item>Earth</item>
        <item>Mars</item>
    </string-array>
</resources> 
1
2
Resources res = getResources();
String[] planets = res.getStringArray(R.array.planets_array); 

Quantity strings (plurals)

  • res/values/filename.xml
  • R.plurals.plural_name
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals
        name="plural_name">
        <item
            quantity=["zero" | "one" | "two" | "few" | "many" | "other"]
            >text_string</item>
    </plurals>
</resources> 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <plurals name="numberOfSongsAvailable">
        <!--
             As a developer, you should always supply "one" and "other"
             strings. Your translators will know which strings are actually
             needed for their language. Always include %d in "one" because
             translators will need to use %d for languages where "one"
             doesn't mean 1 (as explained above).
          -->
        <item quantity="one">%d song found.</item>
        <item quantity="other">%d songs found.</item>
    </plurals>
</resources>
1
2
3
int count = getNumberOfsongsAvailable();
Resources res = getResources();
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count); 

layout

Style

  • Style resource defines the format and look for a UI.
  • res/values/filename.xml
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style
        name="style_name"
        parent="@[package:]style/style_to_inherit">
        <item
            name="[package:]style_property_name"
            >style_value</item>
    </style>
</resources> 
1
2
3
4
5
6
7
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="CustomText" parent="@style/Text">
        <item name="android:textSize">20sp</item>
        <item name="android:textColor">#008</item>
    </style>
</resources> 
1
2
3
4
5
6
<?xml version="1.0" encoding="utf-8"?>
<EditText
    style="@style/CustomText"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="Hello, World!" />