,"Accessing Resources","Accessing Resources in Code ","
You can use a resource in code by passing the resource ID as a method parameter. For example, you can set an ImageView
to use the res/drawable/myimage.png
resource using setImageResource()
:
ImageView imageView = (ImageView) findViewById(R.id.myimageview); imageView.setImageResource(R.drawable.myimage);
You can also retrieve individual resources using methods in Resources
, which you can get an instance of with getResources()
.
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.setBackgroundDrawableResource
(R.drawable.my_background_image) ; // Set the Activity title by getting a string from the Resources object, because // this method requires a CharSequence rather than a resource IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(R.layout.main_screen); // Set a slide in animation by getting an Animation from the Resources object mFlipper.setInAnimation
(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); // Set the text on a TextView object using a resource ID TextView msgTextView = (TextView) findViewById(R.id.msg); msgTextView.setText
(R.string.hello_message);
Caution: You should never modify the R.java
file by hand!it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
A bitmap file is a .png
, .jpg
, or .gif
file. Android creates a Drawable
resource for any of these files when you save them in the res/drawable/
directory.
res/drawable/filename.png
(
.png
,
.jpg
, or
.gif
)
BitmapDrawable
.
R.drawable.filename
@[package:]drawable/filename
res/drawable/myimage.png
, this layout XML applies the image to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/myimage" />
The following application code retrieves the image as a Drawable
:
Resources res =getResources()
; Drawable drawable = res.getDrawable
(R.drawable.myimage);
This is a generic shape defined in XML.
res/drawable/filename.xml
GradientDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>
res/drawable/gradient_box.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape>
This layout XML applies the shape drawable to a View:
<TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
This application code gets the shape drawable and applies it to a View:
Resources res =getResources()
; Drawable shape = res.getDrawable
(R.drawable.gradient_box); TextView tv = (TextView)findViewByID(R.id.textview); tv.setBackground(shape);
You cannot assume anything about the device on which a user will run your application. The device might have hardware that you were not anticipating, or it might be set to a locale that you did not plan for or that you cannot test. Design your application so that it will function normally or fail gracefully no matter what device it runs on.
Important: Make sure that your application includes a full set of default resources.
Make sure to include res/drawable/
and a res/values/
folders (without any additional modifiers in the folder names) that contain all the images and text that your application will need.
If an application is missing even one default resource, it will not run on a device that is set to an unsupported locale. For example, the res/values/strings.xml
default file might lack one string that the application needs: When the application runs in an unsupported locale and attempts to load res/values/strings.xml
, the user will see an error message and a Force Close button. An IDE such as Eclipse will not highlight this kind of error, and you will not see the problem when you test the application on a device or emulator that is set to a supported locale.
For more information, see Testing for Default Resources.
If you need to rearrange your layout to fit a certain language (for example German with its long words), you can create an alternative layout for that language (for example res/layout-de/main.xml
). However, doing this can make your application harder to maintain. It is better to create a single layout that is more flexible.
Another typical situation is a language that requires something different in its layout. For example, you might have a contact form that should include two name fields when the application runs in Japanese, but three name fields when the application runs in some other language. You could handle this in either of two ways:
You probably do not need to create a locale-specific alternative for every resource in your application. For example, the layout defined in the res/layout/main.xml
file might work in any locale, in which case there would be no need to create any alternative layout files.
Also, you might not need to create alternative text for every string. For example, assume the following:
res/values/strings.xml
. To do this, you could create a small file called res/values-en-rGB/strings.xml
that includes only the strings that should be different when the application runs in the U.K. For all the rest of the strings, the application will fall back to the defaults and use what is defined in res/values/strings.xml
.
You can look up the locale using the Context
object that Android makes available:
String locale = context.getResources().getConfiguration().locale.getDisplayName();","Context","android.content.Context","class",0 ,"More Resource Types","Bool","
A boolean value defined in XML.
Note: A bool is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine bool resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<bool>
element's
name
will be used as the resource ID.
R.bool.bool_name
@[package:]bool/bool_name
<?xml version="1.0" encoding="utf-8"?> <resources> <bool name="bool_name" >[true | false]</bool> </resources>
res/values-small/bools.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <bool name="screen_small">true</bool> <bool name="adjust_view_bounds">true</bool> </resources>
This application code retrieves the boolean:
Resources res =getResources()
; boolean screenIsSmall = res.getBoolean
(R.bool.screen_small);
This layout XML uses the boolean for an attribute:
<ImageView android:layout_height="fill_parent" android:layout_width="fill_parent" android:src="@drawable/logo" android:adjustViewBounds="@bool/adjust_view_bounds" />
A color value defined in XML. The color is specified with an RGB value and alpha channel. You can use a color resource any place that accepts a hexadecimal color value. You can also use a color resource when a drawable resource is expected in XML (for example, android:drawable="@color/green"
).
The value always begins with a pound (#) character and then followed by the Alpha-Red-Green-Blue information in one of the following formats:
Note: A color is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine color resources with other simple resources in the one XML file, under one <resources>
element.
res/values/colors.xml
<color>
element's
name
will be used as the resource ID.
R.color.color_name
@[package:]color/color_name
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="color_name" >hex_color</color> </resources>
res/values/colors.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="opaque_red">#f00</color> <color name="translucent_red">#80ff0000</color> </resources>
This application code retrieves the color resource:
Resources res =getResources()
; int color = res.getColor
(R.color.opaque_red);
This layout XML applies the color to an attribute:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@color/translucent_red" android:text="Hello"/>
A dimension value defined in XML. A dimension is specified with a number followed by a unit of measure. For example: 10px, 2in, 5sp. The following units of measure are supported by Android:
dp
sp
pt
px
mm
in
Note: A dimension is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine dimension resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<dimen>
element's
name
will be used as the resource ID.
R.dimen.dimension_name
@[package:]dimen/dimension_name
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="dimension_name" >dimension</dimen> </resources>
res/values/dimens.xml
:
<?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>
This application code retrieves a dimension:
Resources res =getResources()
; float fontSize = res.getDimension
(R.dimen.font_size);
This layout XML applies dimensions to attributes:
<TextView android:layout_height="@dimen/textview_height" android:layout_width="@dimen/textview_width" android:textSize="@dimen/font_size"/>
An integer defined in XML.
Note: An integer is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine integer resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<integer>
element's
name
will be used as the resource ID.
R.integer.integer_name
@[package:]integer/integer_name
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="integer_name" >integer</integer> </resources>
XML file saved at res/values/integers.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="max_speed">75</integer> <integer name="min_speed">5</integer> </resources>
This application code retrieves an integer:
Resources res =getResources()
; int maxSpeed = res.getInteger
(R.integer.max_speed);
An array of integers defined in XML.
Note: An integer array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine integer array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<integer-array>
element's
name
will be used as the resource ID.
R.array.integer_array_name
@[package:]array.integer_array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <integer-array name="integer_array_name"> <item >integer</item> </integer-array> </resources>
res/values/integers.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer-array name="bits"> <item>4</item> <item>8</item> <item>16</item> <item>32</item> </integer-array> </resources>
This application code retrieves the integer array:
Resources res =getResources()
; int[] bits = res.getIntArray
(R.array.bits);
A TypedArray
defined in XML. You can use this to create an array of other resources, such as drawables. Note that the array is not required to be homogeneous, so you can create an array of mixed resource types, but you must be aware of what and where the data types are in the array so that you can properly obtain each item with the TypedArray
's get...()
methods.
Note: A typed array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine typed array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<array>
element's
name
will be used as the resource ID.
TypedArray
.
R.array.array_name
@[package:]array.array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="integer_array_name"> <item>resource</item> </array> </resources>
res/values/arrays.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="icons"> <item>@drawable/home</item> <item>@drawable/settings</item> <item>@drawable/logout</item> </array> <array name="colors"> <item>#FFFF0000</item> <item>#FF00FF00</item> <item>#FF0000FF</item> </array> </resources>
This application code retrieves each array and then obtains the first entry in each array:
Resources res =getResources()
; TypedArray icons = res.obtainTypedArray
(R.array.icons); Drawable drawable = icons.getDrawable
(0); TypedArray colors = res.obtainTypedArray
(R.array.colors); int color = colors.getColor
(0,0);
res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
This layout XML applies a string to a View:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
This application code retrieves a string:
String string = getString
(R.string.hello);
You can use either getString(int)
or getText(int)
to retrieve a string. getText(int)
will retain any rich text styling applied to the string.
An array of strings that can be referenced from the application.
Note: A string array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine string array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<string-array>
element's
name
will be used as the resource ID.
String
s.
R.array.string_array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
res/values/strings.xml
:
<?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>
This application code retrieves a string array:
Resources res =getResources()
; String[] planets = res.getStringArray
(R.array.planets_array);
Different languages have different rules for grammatical agreement with quantity. In English, for example, the quantity 1 is a special case. We write "1 book", but for any other quantity we'd write "n books". This distinction between singular and plural is very common, but other languages make finer distinctions. The full set supported by Android is zero
, one
, two
, few
, many
, and other
.
The rules for deciding which case to use for a given language and quantity can be very complex, so Android provides you with methods such as getQuantityString()
to select the appropriate resource for you.
Although historically called "quantity strings" (and still called that in API), quantity strings should only be used for plurals. It would be a mistake to use quantity strings to implement something like Gmail's "Inbox" versus "Inbox (12)" when there are unread messages, for example. It might seem convenient to use quantity strings instead of an if
statement, but it's important to note that some languages (such as Chinese) don't make these grammatical distinctions at all, so you'll always get the other
string.
The selection of which string to use is made solely based on grammatical necessity. In English, a string for zero
will be ignored even if the quantity is 0, because 0 isn't grammatically different from 2, or any other number except 1 ("zero books", "one book", "two books", and so on).
Don't be misled either by the fact that, say, two
sounds like it could only apply to the quantity 2: a language may require that 2, 12, 102 (and so on) are all treated like one another but differently to other quantities. Rely on your translator to know what distinctions their language actually insists upon.
It's often possible to avoid quantity strings by using quantity-neutral formulations such as "Books: 1". This will make your life and your translators' lives easier, if it's a style that's in keeping with your application.
Note: A plurals collection is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine plurals resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<plurals>
element's
name
will be used as the resource ID.
R.plurals.plural_name
<?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>
res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <item quantity="one">One song found.</item> <item quantity="other">%d songs found.</item> </plurals> </resources>
XML file saved at res/values-pl/strings.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <item quantity="one">Znaleziono jedn? piosenk?.</item> <item quantity="few">Znaleziono %d piosenki.</item> <item quantity="other">Znaleziono %d piosenek.</item> </plurals> </resources>
Java code:
int count = getNumberOfsongsAvailable();
Resources res = getResources()
;
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);
When using the getQuantityString()
method, you need to pass the count
twice if your string includes string formatting with a number. For example, for the string %d songs found
, the first count
parameter selects the appropriate plural string and the second count
parameter is inserted into the %d
placeholder. If your plural strings do not include string formatting, you don't need to pass the third parameter to getQuantityString
.
If you need to format your strings using String.format(String, Object...)
, then you can do so by putting your format arguments in the string resource. For example, with the following resource:
<string name="welcome_messages">Hello, %1$s! You have %2$d new messages.</string>
In this example, the format string has two arguments: %1$s
is a string and %2$d
is a decimal number. You can format the string with arguments from your application like this:
Resources res = getResources()
;
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
","Context","android.content.Context","class",1
,"Formatting and Styling","Styling with HTML markup","You can add styling to your strings with HTML markup. For example:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Supported HTML elements include:
<b>
for bold text.<i>
for italic text.<u>
for underline text.Sometimes you may want to create a styled text resource that is also used as a format string. Normally, this won't work because the String.format(String, Object...)
method will strip all the style information from the string. The work-around to this is to write the HTML tags with escaped entities, which are then recovered with fromHtml(String)
, after the formatting takes place. For example:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
In this formatted string, a <b>
element is added. Notice that the opening bracket is HTML-escaped, using the <
notation.
fromHtml(String)
to convert the HTML text into styled text:
Resources res = getResources()
;
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
CharSequence styledText = Html.fromHtml(text);
Because the fromHtml(String)
method will format all HTML entities, be sure to escape any possible HTML characters in the strings you use with the formatted text, using htmlEncode(String)
. For instance, if you'll be passing a string argument to String.format()
that may contain characters such as "<" or "&", then they must be escaped before formatting, so that when the formatted string is passed through fromHtml(String)
, the characters come out the way they were originally written. For example:
String escapedUsername = TextUtil.htmlEncode
(username); Resources res =getResources()
; String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount); CharSequence styledText = Html.fromHtml(text);
You can use a resource in code by passing the resource ID as a method parameter. For example, you can set an ImageView
to use the res/drawable/myimage.png
resource using setImageResource()
:
ImageView imageView = (ImageView) findViewById(R.id.myimageview); imageView.setImageResource(R.drawable.myimage);
You can also retrieve individual resources using methods in Resources
, which you can get an instance of with getResources()
.
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
A Drawable that manages a number of alternate Drawables, each assigned a maximum numerical value. Setting the level value of the drawable with setLevel()
loads the drawable resource in the level list that has a android:maxLevel
value greater than or equal to the value passed to the method.
res/drawable/filename.xml
LevelListDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/drawable_resource" android:maxLevel="integer" android:minLevel="integer" /> </level-list>
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/status_off" android:maxLevel="0" /> <item android:drawable="@drawable/status_on" android:maxLevel="1" /> </level-list>
Once this is applied to a View
, the level can be changed with setLevel()
or setImageLevel()
.
This is a generic shape defined in XML.
res/drawable/filename.xml
GradientDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>
res/drawable/gradient_box.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape>
This layout XML applies the shape drawable to a View:
<TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
This application code gets the shape drawable and applies it to a View:
Resources res =getResources()
; Drawable shape = res.getDrawable
(R.drawable.gradient_box); TextView tv = (TextView)findViewByID(R.id.textview); tv.setBackground(shape);
If your application doesn't need to update resources during a specific configuration change and you have a performance limitation that requires you to avoid the activity restart, then you can declare that your activity handles the configuration change itself, which prevents the system from restarting your activity.
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
To declare that your activity handles a configuration change, edit the appropriate <activity>
element in your manifest file to include the android:configChanges
attribute with a value that represents the configuration you want to handle. Possible values are listed in the documentation for the android:configChanges
attribute (the most commonly used values are "orientation"
to prevent restarts when the screen orientation changes and "keyboardHidden"
to prevent restarts when the keyboard availability changes). You can declare multiple configuration values in the attribute by separating them with a pipe |
character.
For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
Now, when one of these configurations change, MyActivity
does not restart. Instead, the MyActivity
receives a call to onConfigurationChanged()
. This method is passed a Configuration
object that specifies the new device configuration. By reading fields in the Configuration
, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources
object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion
and targetSdkVersion
attributes), you must include the "screenSize"
value in addition to the "orientation"
value. That is, you must decalare android:configChanges="orientation|screenSize"
. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
For example, the following onConfigurationChanged()
implementation checks the current device orientation:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); } }
The Configuration
object represents all of the current configurations, not just the ones that have changed. Most of the time, you won't care exactly how the configuration has changed and can simply re-assign all your resources that provide alternatives to the configuration that you're handling. For example, because the Resources
object is now updated, you can reset any ImageView
s with setImageResource()
and the appropriate resource for the new configuration is used (as described in Providing Resources).
Notice that the values from the Configuration
fields are integers that are matched to specific constants from the Configuration
class. For documentation about which constants to use with each field, refer to the appropriate field in the Configuration
reference.
Remember: When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during onConfigurationChanged()
.
If you don't need to update your application based on these configuration changes, you can instead not implement onConfigurationChanged()
. In which case, all of the resources used before the configuration change are still used and you've only avoided the restart of your activity. However, your application should always be able to shutdown and restart with its previous state intact, so you should not consider this technique an escape from retaining your state during normal activity lifecycle. Not only because there are other configuration changes that you cannot prevent from restarting your application, but also because you should handle events such as when the user leaves your application and it gets destroyed before the user returns to it.
For more about which configuration changes you can handle in your activity, see the android:configChanges
documentation and the Configuration
class.
You can use a resource in code by passing the resource ID as a method parameter. For example, you can set an ImageView
to use the res/drawable/myimage.png
resource using setImageResource()
:
ImageView imageView = (ImageView) findViewById(R.id.myimageview); imageView.setImageResource(R.drawable.myimage);
You can also retrieve individual resources using methods in Resources
, which you can get an instance of with getResources()
.
While uncommon, you might need access your original files and directories. If you do, then saving your files in res/
won't work for you, because the only way to read a resource from res/
is with the resource ID. Instead, you can save your resources in the assets/
directory.
Files saved in the assets/
directory are not given a resource ID, so you can't reference them through the R
class or from XML resources. Instead, you can query files in the assets/
directory like a normal file system and read raw data using AssetManager
.
However, if all you require is the ability to read raw data (such as a video or audio file), then save the file in the res/raw/
directory and read a stream of bytes using openRawResource()
.
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.setBackgroundDrawableResource
(R.drawable.my_background_image) ; // Set the Activity title by getting a string from the Resources object, because // this method requires a CharSequence rather than a resource IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(R.layout.main_screen); // Set a slide in animation by getting an Animation from the Resources object mFlipper.setInAnimation
(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); // Set the text on a TextView object using a resource ID TextView msgTextView = (TextView) findViewById(R.id.msg); msgTextView.setText
(R.string.hello_message);
Caution: You should never modify the R.java
file by hand!it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A bitmap file is a .png
, .jpg
, or .gif
file. Android creates a Drawable
resource for any of these files when you save them in the res/drawable/
directory.
res/drawable/filename.png
(
.png
,
.jpg
, or
.gif
)
BitmapDrawable
.
R.drawable.filename
@[package:]drawable/filename
res/drawable/myimage.png
, this layout XML applies the image to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/myimage" />
The following application code retrieves the image as a Drawable
:
Resources res =getResources()
; Drawable drawable = res.getDrawable
(R.drawable.myimage);
This is a generic shape defined in XML.
res/drawable/filename.xml
GradientDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>
res/drawable/gradient_box.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape>
This layout XML applies the shape drawable to a View:
<TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
This application code gets the shape drawable and applies it to a View:
Resources res =getResources()
; Drawable shape = res.getDrawable
(R.drawable.gradient_box); TextView tv = (TextView)findViewByID(R.id.textview); tv.setBackground(shape);
A boolean value defined in XML.
Note: A bool is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine bool resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<bool>
element's
name
will be used as the resource ID.
R.bool.bool_name
@[package:]bool/bool_name
<?xml version="1.0" encoding="utf-8"?> <resources> <bool name="bool_name" >[true | false]</bool> </resources>
res/values-small/bools.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <bool name="screen_small">true</bool> <bool name="adjust_view_bounds">true</bool> </resources>
This application code retrieves the boolean:
Resources res =getResources()
; boolean screenIsSmall = res.getBoolean
(R.bool.screen_small);
This layout XML uses the boolean for an attribute:
<ImageView android:layout_height="fill_parent" android:layout_width="fill_parent" android:src="@drawable/logo" android:adjustViewBounds="@bool/adjust_view_bounds" />
A color value defined in XML. The color is specified with an RGB value and alpha channel. You can use a color resource any place that accepts a hexadecimal color value. You can also use a color resource when a drawable resource is expected in XML (for example, android:drawable="@color/green"
).
The value always begins with a pound (#) character and then followed by the Alpha-Red-Green-Blue information in one of the following formats:
Note: A color is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine color resources with other simple resources in the one XML file, under one <resources>
element.
res/values/colors.xml
<color>
element's
name
will be used as the resource ID.
R.color.color_name
@[package:]color/color_name
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="color_name" >hex_color</color> </resources>
res/values/colors.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <color name="opaque_red">#f00</color> <color name="translucent_red">#80ff0000</color> </resources>
This application code retrieves the color resource:
Resources res =getResources()
; int color = res.getColor
(R.color.opaque_red);
This layout XML applies the color to an attribute:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:textColor="@color/translucent_red" android:text="Hello"/>
A dimension value defined in XML. A dimension is specified with a number followed by a unit of measure. For example: 10px, 2in, 5sp. The following units of measure are supported by Android:
dp
sp
pt
px
mm
in
Note: A dimension is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine dimension resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<dimen>
element's
name
will be used as the resource ID.
R.dimen.dimension_name
@[package:]dimen/dimension_name
<?xml version="1.0" encoding="utf-8"?> <resources> <dimen name="dimension_name" >dimension</dimen> </resources>
res/values/dimens.xml
:
<?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>
This application code retrieves a dimension:
Resources res =getResources()
; float fontSize = res.getDimension
(R.dimen.font_size);
This layout XML applies dimensions to attributes:
<TextView android:layout_height="@dimen/textview_height" android:layout_width="@dimen/textview_width" android:textSize="@dimen/font_size"/>
An integer defined in XML.
Note: An integer is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine integer resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<integer>
element's
name
will be used as the resource ID.
R.integer.integer_name
@[package:]integer/integer_name
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="integer_name" >integer</integer> </resources>
XML file saved at res/values/integers.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer name="max_speed">75</integer> <integer name="min_speed">5</integer> </resources>
This application code retrieves an integer:
Resources res =getResources()
; int maxSpeed = res.getInteger
(R.integer.max_speed);
An array of integers defined in XML.
Note: An integer array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine integer array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<integer-array>
element's
name
will be used as the resource ID.
R.array.integer_array_name
@[package:]array.integer_array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <integer-array name="integer_array_name"> <item >integer</item> </integer-array> </resources>
res/values/integers.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <integer-array name="bits"> <item>4</item> <item>8</item> <item>16</item> <item>32</item> </integer-array> </resources>
This application code retrieves the integer array:
Resources res =getResources()
; int[] bits = res.getIntArray
(R.array.bits);
A TypedArray
defined in XML. You can use this to create an array of other resources, such as drawables. Note that the array is not required to be homogeneous, so you can create an array of mixed resource types, but you must be aware of what and where the data types are in the array so that you can properly obtain each item with the TypedArray
's get...()
methods.
Note: A typed array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine typed array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<array>
element's
name
will be used as the resource ID.
TypedArray
.
R.array.array_name
@[package:]array.array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="integer_array_name"> <item>resource</item> </array> </resources>
res/values/arrays.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="icons"> <item>@drawable/home</item> <item>@drawable/settings</item> <item>@drawable/logout</item> </array> <array name="colors"> <item>#FFFF0000</item> <item>#FF00FF00</item> <item>#FF0000FF</item> </array> </resources>
This application code retrieves each array and then obtains the first entry in each array:
Resources res =getResources()
; TypedArray icons = res.obtainTypedArray
(R.array.icons); Drawable drawable = icons.getDrawable
(0); TypedArray colors = res.obtainTypedArray
(R.array.colors); int color = colors.getColor
(0,0);
You should place each type of resource in a specific subdirectory of your project's res/
directory. For example, here's the file hierarchy for a simple project:
MyProject/ src/ MyActivity.java res/ drawable/ icon.png layout/ main.xml info.xml values/ strings.xml
As you can see in this example, the res/
directory contains all the resources (in subdirectories): an image resource, two layout resources, and a string resource file. The resource directory names are important and are described in table 1.
Directory | Resource Type |
---|---|
animator/ |
XML files that define property animations. |
anim/ |
XML files that define tween animations. (Property animations can also be saved in this directory, but the animator/ directory is preferred for property animations to distinguish between the two types.) |
color/ |
XML files that define a state list of colors. See Color State List Resource |
drawable/ |
Bitmap files (
See Drawable Resources. |
layout/ |
XML files that define a user interface layout. See Layout Resource. |
menu/ |
XML files that define application menus, such as an Options Menu, Context Menu, or Sub Menu. See Menu Resource. |
raw/ |
Arbitrary files to save in their raw form. To open these resources with a raw However, if you need access to original file names and file hierarchy, you might consider saving some resources in the |
values/ |
XML files that contain simple values, such as strings, integers, and colors. Whereas XML resource files in other Because each resource is defined with its own XML element, you can name the file whatever you want and place different resource types in one file. However, for clarity, you might want to place unique resource types in different files. For example, here are some filename conventions for resources you can create in this directory:
See String Resources, Style Resource, and More Resource Types. |
xml/ |
Arbitrary XML files that can be read at runtime by calling Resources.getXML() . Various XML configuration files must be saved here, such as a searchable configuration.
|
Caution: Never save resource files directly inside the res/
directory!it will cause a compiler error.
For more information about certain types of resources, see the Resource Types documentation.
The resources that you save in the subdirectories defined in table 1 are your "default" resources. That is, these resources define the default design and content for your application. However, different types of Android-powered devices might call for different types of resources. For example, if a device has a larger than normal screen, then you should provide different layout resources that take advantage of the extra screen space. Or, if a device has a different language setting, then you should provide different string resources that translate the text in your user interface. To provide these different resources for different device configurations, you need to provide alternative resources, in addition to your default resources.
","Resources","android.content.res.Resources","class",1 ,"Handling Runtime Changes","Handling the Configuration Change Yourself","If your application doesn't need to update resources during a specific configuration change and you have a performance limitation that requires you to avoid the activity restart, then you can declare that your activity handles the configuration change itself, which prevents the system from restarting your activity.
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
To declare that your activity handles a configuration change, edit the appropriate <activity>
element in your manifest file to include the android:configChanges
attribute with a value that represents the configuration you want to handle. Possible values are listed in the documentation for the android:configChanges
attribute (the most commonly used values are "orientation"
to prevent restarts when the screen orientation changes and "keyboardHidden"
to prevent restarts when the keyboard availability changes). You can declare multiple configuration values in the attribute by separating them with a pipe |
character.
For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
Now, when one of these configurations change, MyActivity
does not restart. Instead, the MyActivity
receives a call to onConfigurationChanged()
. This method is passed a Configuration
object that specifies the new device configuration. By reading fields in the Configuration
, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources
object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion
and targetSdkVersion
attributes), you must include the "screenSize"
value in addition to the "orientation"
value. That is, you must decalare android:configChanges="orientation|screenSize"
. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
For example, the following onConfigurationChanged()
implementation checks the current device orientation:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); } }
The Configuration
object represents all of the current configurations, not just the ones that have changed. Most of the time, you won't care exactly how the configuration has changed and can simply re-assign all your resources that provide alternatives to the configuration that you're handling. For example, because the Resources
object is now updated, you can reset any ImageView
s with setImageResource()
and the appropriate resource for the new configuration is used (as described in Providing Resources).
Notice that the values from the Configuration
fields are integers that are matched to specific constants from the Configuration
class. For documentation about which constants to use with each field, refer to the appropriate field in the Configuration
reference.
Remember: When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during onConfigurationChanged()
.
If you don't need to update your application based on these configuration changes, you can instead not implement onConfigurationChanged()
. In which case, all of the resources used before the configuration change are still used and you've only avoided the restart of your activity. However, your application should always be able to shutdown and restart with its previous state intact, so you should not consider this technique an escape from retaining your state during normal activity lifecycle. Not only because there are other configuration changes that you cannot prevent from restarting your application, but also because you should handle events such as when the user leaves your application and it gets destroyed before the user returns to it.
For more about which configuration changes you can handle in your activity, see the android:configChanges
documentation and the Configuration
class.
An array of strings that can be referenced from the application.
Note: A string array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine string array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<string-array>
element's
name
will be used as the resource ID.
String
s.
R.array.string_array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
res/values/strings.xml
:
<?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>
This application code retrieves a string array:
Resources res =getResources()
; String[] planets = res.getStringArray
(R.array.planets_array);
Different languages have different rules for grammatical agreement with quantity. In English, for example, the quantity 1 is a special case. We write "1 book", but for any other quantity we'd write "n books". This distinction between singular and plural is very common, but other languages make finer distinctions. The full set supported by Android is zero
, one
, two
, few
, many
, and other
.
The rules for deciding which case to use for a given language and quantity can be very complex, so Android provides you with methods such as getQuantityString()
to select the appropriate resource for you.
Although historically called "quantity strings" (and still called that in API), quantity strings should only be used for plurals. It would be a mistake to use quantity strings to implement something like Gmail's "Inbox" versus "Inbox (12)" when there are unread messages, for example. It might seem convenient to use quantity strings instead of an if
statement, but it's important to note that some languages (such as Chinese) don't make these grammatical distinctions at all, so you'll always get the other
string.
The selection of which string to use is made solely based on grammatical necessity. In English, a string for zero
will be ignored even if the quantity is 0, because 0 isn't grammatically different from 2, or any other number except 1 ("zero books", "one book", "two books", and so on).
Don't be misled either by the fact that, say, two
sounds like it could only apply to the quantity 2: a language may require that 2, 12, 102 (and so on) are all treated like one another but differently to other quantities. Rely on your translator to know what distinctions their language actually insists upon.
It's often possible to avoid quantity strings by using quantity-neutral formulations such as "Books: 1". This will make your life and your translators' lives easier, if it's a style that's in keeping with your application.
Note: A plurals collection is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine plurals resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<plurals>
element's
name
will be used as the resource ID.
R.plurals.plural_name
<?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>
res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <item quantity="one">One song found.</item> <item quantity="other">%d songs found.</item> </plurals> </resources>
XML file saved at res/values-pl/strings.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <plurals name="numberOfSongsAvailable"> <item quantity="one">Znaleziono jedn? piosenk?.</item> <item quantity="few">Znaleziono %d piosenki.</item> <item quantity="other">Znaleziono %d piosenek.</item> </plurals> </resources>
Java code:
int count = getNumberOfsongsAvailable();
Resources res = getResources()
;
String songsFound = res.getQuantityString(R.plurals.numberOfSongsAvailable, count, count);
When using the getQuantityString()
method, you need to pass the count
twice if your string includes string formatting with a number. For example, for the string %d songs found
, the first count
parameter selects the appropriate plural string and the second count
parameter is inserted into the %d
placeholder. If your plural strings do not include string formatting, you don't need to pass the third parameter to getQuantityString
.
While uncommon, you might need access your original files and directories. If you do, then saving your files in res/
won't work for you, because the only way to read a resource from res/
is with the resource ID. Instead, you can save your resources in the assets/
directory.
Files saved in the assets/
directory are not given a resource ID, so you can't reference them through the R
class or from XML resources. Instead, you can query files in the assets/
directory like a normal file system and read raw data using AssetManager
.
However, if all you require is the ability to read raw data (such as a video or audio file), then save the file in the res/raw/
directory and read a stream of bytes using openRawResource()
.
An alternative to saving files in res/
is to save files in the assets/
directory. This should only be necessary if you need direct access to original files and
directories by name. Files saved in the assets/
directory will not be given a resource
ID, so you can't reference them through the R
class or from XML resources. Instead, you can
query data in the assets/
directory like an ordinary file system, search through the
directory and
read raw data using AssetManager
. For example, this can be more useful
when dealing with textures for a game. However, if you only need to read raw data from a file
(such as a video or audio file), then you should save files into the res/raw/
directory and
then read a stream of bytes using openRawResource(int)
. This
is uncommon, but if you need direct access to original files in assets/
, refer to the AssetManager
documentation.
You should place each type of resource in a specific subdirectory of your project's res/
directory. For example, here's the file hierarchy for a simple project:
MyProject/ src/ MyActivity.java res/ drawable/ icon.png layout/ main.xml info.xml values/ strings.xml
As you can see in this example, the res/
directory contains all the resources (in subdirectories): an image resource, two layout resources, and a string resource file. The resource directory names are important and are described in table 1.
Directory | Resource Type |
---|---|
animator/ |
XML files that define property animations. |
anim/ |
XML files that define tween animations. (Property animations can also be saved in this directory, but the animator/ directory is preferred for property animations to distinguish between the two types.) |
color/ |
XML files that define a state list of colors. See Color State List Resource |
drawable/ |
Bitmap files (
See Drawable Resources. |
layout/ |
XML files that define a user interface layout. See Layout Resource. |
menu/ |
XML files that define application menus, such as an Options Menu, Context Menu, or Sub Menu. See Menu Resource. |
raw/ |
Arbitrary files to save in their raw form. To open these resources with a raw However, if you need access to original file names and file hierarchy, you might consider saving some resources in the |
values/ |
XML files that contain simple values, such as strings, integers, and colors. Whereas XML resource files in other Because each resource is defined with its own XML element, you can name the file whatever you want and place different resource types in one file. However, for clarity, you might want to place unique resource types in different files. For example, here are some filename conventions for resources you can create in this directory:
See String Resources, Style Resource, and More Resource Types. |
xml/ |
Arbitrary XML files that can be read at runtime by calling Resources.getXML() . Various XML configuration files must be saved here, such as a searchable configuration.
|
Caution: Never save resource files directly inside the res/
directory!it will cause a compiler error.
For more information about certain types of resources, see the Resource Types documentation.
The resources that you save in the subdirectories defined in table 1 are your "default" resources. That is, these resources define the default design and content for your application. However, different types of Android-powered devices might call for different types of resources. For example, if a device has a larger than normal screen, then you should provide different layout resources that take advantage of the extra screen space. Or, if a device has a different language setting, then you should provide different string resources that translate the text in your user interface. To provide these different resources for different device configurations, you need to provide alternative resources, in addition to your default resources.
","AssetManager","android.content.res.AssetManager","class",0 ,"Access to Original Files","Use cases","There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.setBackgroundDrawableResource
(R.drawable.my_background_image) ; // Set the Activity title by getting a string from the Resources object, because // this method requires a CharSequence rather than a resource IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(R.layout.main_screen); // Set a slide in animation by getting an Animation from the Resources object mFlipper.setInAnimation
(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); // Set the text on a TextView object using a resource ID TextView msgTextView = (TextView) findViewById(R.id.msg); msgTextView.setText
(R.string.hello_message);
Caution: You should never modify the R.java
file by hand!it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.setBackgroundDrawableResource
(R.drawable.my_background_image) ; // Set the Activity title by getting a string from the Resources object, because // this method requires a CharSequence rather than a resource IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(R.layout.main_screen); // Set a slide in animation by getting an Animation from the Resources object mFlipper.setInAnimation
(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); // Set the text on a TextView object using a resource ID TextView msgTextView = (TextView) findViewById(R.id.msg); msgTextView.setText
(R.string.hello_message);
Caution: You should never modify the R.java
file by hand!it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.setBackgroundDrawableResource
(R.drawable.my_background_image) ; // Set the Activity title by getting a string from the Resources object, because // this method requires a CharSequence rather than a resource IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(R.layout.main_screen); // Set a slide in animation by getting an Animation from the Resources object mFlipper.setInAnimation
(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); // Set the text on a TextView object using a resource ID TextView msgTextView = (TextView) findViewById(R.id.msg); msgTextView.setText
(R.string.hello_message);
Caution: You should never modify the R.java
file by hand!it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
There are many methods that accept a resource ID parameter and you can retrieve resources using methods in Resources
. You can get an instance of Resources
with Context.getResources()
.
Here are some examples of accessing resources in code:
// Load a background for the current screen from a drawable resourcegetWindow()
.setBackgroundDrawableResource
(R.drawable.my_background_image) ; // Set the Activity title by getting a string from the Resources object, because // this method requires a CharSequence rather than a resource IDgetWindow()
.setTitle
(getResources().getText
(R.string.main_title)); // Load a custom layout for the current screensetContentView
(R.layout.main_screen); // Set a slide in animation by getting an Animation from the Resources object mFlipper.setInAnimation
(AnimationUtils.loadAnimation(this, R.anim.hyperspace_in)); // Set the text on a TextView object using a resource ID TextView msgTextView = (TextView) findViewById(R.id.msg); msgTextView.setText
(R.string.hello_message);
Caution: You should never modify the R.java
file by hand!it is generated by the aapt
tool when your project is compiled. Any changes are overridden next time you compile.
A LayerDrawable
is a drawable object that manages an array of other drawables. Each drawable in the list is drawn in the order of the list!the last drawable in the list is drawn on top.
Each drawable is represented by an <item>
element inside a single <layer-list>
element.
res/drawable/filename.xml
LayerDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </layer-list>
res/drawable/layers.xml
:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:src="@drawable/android_red" android:gravity="center" /> </item> <item android:top="10dp" android:left="10dp"> <bitmap android:src="@drawable/android_green" android:gravity="center" /> </item> <item android:top="20dp" android:left="20dp"> <bitmap android:src="@drawable/android_blue" android:gravity="center" /> </item> </layer-list>
Notice that this example uses a nested <bitmap>
element to define the drawable resource for each item with a "center" gravity. This ensures that none of the images are scaled to fit the size of the container, due to resizing caused by the offset images.
This layout XML applies the drawable to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/layers" />
The result is a stack of increasingly offset images:
A TransitionDrawable
is a drawable object that can cross-fade between the two drawable resources.
Each drawable is represented by an <item>
element inside a single <transition>
element. No more than two items are supported. To transition forward, call startTransition()
. To transition backward, call reverseTransition()
.
res/drawable/filename.xml
TransitionDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </transition>
res/drawable/transition.xml
:
<?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>
This layout XML applies the drawable to a View:
<ImageButton android:id="@+id/button" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/transition" />
And the following code performs a 500ms transition from the first item to the second:
ImageButton button = (ImageButton) findViewById(R.id.button); TransitionDrawable drawable = (TransitionDrawable) button.getDrawable(); drawable.startTransition(500);
A unique resource ID defined in XML. Using the name you provide in the <item>
element, the Android developer tools create a unique integer in your project's R.java
class, which you can use as an identifier for an application resources (for example, a View
in your UI layout) or a unique integer for use in your application code (for example, as an ID for a dialog or a result code).
Note: An ID is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine ID resources with other simple resources in the one XML file, under one <resources>
element. Also, remember that an ID resources does not reference an actual resource item; it is simply a unique ID that you can attach to other resources or use as a unique integer in your application.
res/values/filename.xml
R.id.name
@[package:]id/name
<?xml version="1.0" encoding="utf-8"?> <resources> <item type="id" name="id_name" /> </resources>
XML file saved at res/values/ids.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <item type="id" name="button_ok" /> <item type="id" name="dialog_exit" /> </resources>
Then, this layout snippet uses the "button_ok" ID for a Button widget:
<Button android:id="@id/button_ok" style="@style/button_style" />
Notice that the android:id
value does not include the plus sign in the ID reference, because the ID already exists, as defined in the ids.xml
example above. (When you specify an ID to an XML resource using the plus sign!in the format android:id="@+id/name"
!it means that the "name" ID does not exist and should be created.)
As another example, the following code snippet uses the "dialog_exit" ID as a unique identifier for a dialog:
showDialog
(R.id.dialog_exit);
In the same application, the "dialog_exit" ID is compared when creating a dialog:
protected Dialog onCreateDialog(int)
(int id) {
Dialog dialog;
switch(id) {
case R.id.dialog_exit:
...
break;
default:
dialog = null;
}
return dialog;
}
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity
(onDestroy()
is called, followed by onCreate()
). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that match the new device configuration.
To properly handle a restart, it is important that your activity restores its previous state through the normal Activity lifecycle, in which Android calls onSaveInstanceState()
before it destroys your activity so that you can save data about the application state. You can then restore the state during onCreate()
or onRestoreInstanceState()
.
To test that your application restarts itself with the application state intact, you should invoke configuration changes (such as changing the screen orientation) while performing various tasks in your application. Your application should be able to restart at any time without loss of user data or state in order to handle events such as configuration changes or when the user receives an incoming phone call and then returns to your application much later after your application process may have been destroyed. To learn how you can restore your activity state, read about the Activity lifecycle.
However, you might encounter a situation in which restarting your application and restoring significant amounts of data can be costly and create a poor user experience. In such a situation, you have two other options:
Allow your activity to restart when a configuration changes, but carry a stateful Object
to the new instance of your activity.
Prevent the system from restarting your activity during certain configuration changes, but receive a callback when the configurations do change, so that you can manually update your activity as necessary.
If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle
that the system saves for you with the onSaveInstanceState()
callback!it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object
when your activity is restarted due to a configuration change.
To retain an object during a runtime configuration change:
onRetainNonConfigurationInstance()
method to return the object you would like to retain.getLastNonConfigurationInstance()
to recover your object.When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance()
between the onStop()
and onDestroy()
callbacks. In your implementation of onRetainNonConfigurationInstance()
, you can return any Object
that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance()
to return an object carrying your data and then retrieve the data when your activity starts again with getLastNonConfigurationInstance()
. For example:
@Override public Object onRetainNonConfigurationInstance() { final MyDataObject data = collectMyLoadedData(); return data; }
Caution: While you can return any object, you should never pass an object that is tied to the Activity
, such as a Drawable
, an Adapter
, a View
or any other object that's associated with a Context
. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)
Then retrieve the data when your activity starts again:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); if (data == null) { data = loadMyData(); } ... }
In this case, getLastNonConfigurationInstance()
returns the data saved by onRetainNonConfigurationInstance()
. If data
is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.
If your application doesn't need to update resources during a specific configuration change and you have a performance limitation that requires you to avoid the activity restart, then you can declare that your activity handles the configuration change itself, which prevents the system from restarting your activity.
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
To declare that your activity handles a configuration change, edit the appropriate <activity>
element in your manifest file to include the android:configChanges
attribute with a value that represents the configuration you want to handle. Possible values are listed in the documentation for the android:configChanges
attribute (the most commonly used values are "orientation"
to prevent restarts when the screen orientation changes and "keyboardHidden"
to prevent restarts when the keyboard availability changes). You can declare multiple configuration values in the attribute by separating them with a pipe |
character.
For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
Now, when one of these configurations change, MyActivity
does not restart. Instead, the MyActivity
receives a call to onConfigurationChanged()
. This method is passed a Configuration
object that specifies the new device configuration. By reading fields in the Configuration
, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources
object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion
and targetSdkVersion
attributes), you must include the "screenSize"
value in addition to the "orientation"
value. That is, you must decalare android:configChanges="orientation|screenSize"
. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
For example, the following onConfigurationChanged()
implementation checks the current device orientation:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); } }
The Configuration
object represents all of the current configurations, not just the ones that have changed. Most of the time, you won't care exactly how the configuration has changed and can simply re-assign all your resources that provide alternatives to the configuration that you're handling. For example, because the Resources
object is now updated, you can reset any ImageView
s with setImageResource()
and the appropriate resource for the new configuration is used (as described in Providing Resources).
Notice that the values from the Configuration
fields are integers that are matched to specific constants from the Configuration
class. For documentation about which constants to use with each field, refer to the appropriate field in the Configuration
reference.
Remember: When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during onConfigurationChanged()
.
If you don't need to update your application based on these configuration changes, you can instead not implement onConfigurationChanged()
. In which case, all of the resources used before the configuration change are still used and you've only avoided the restart of your activity. However, your application should always be able to shutdown and restart with its previous state intact, so you should not consider this technique an escape from retaining your state during normal activity lifecycle. Not only because there are other configuration changes that you cannot prevent from restarting your application, but also because you should handle events such as when the user leaves your application and it gets destroyed before the user returns to it.
For more about which configuration changes you can handle in your activity, see the android:configChanges
documentation and the Configuration
class.
You can define values for some XML attributes and elements using a reference to an existing resource. You will often do this when creating layout files, to supply strings and images for your widgets.
For example, if you add a Button
to your layout, you should use a string resource for the button text:
<Button android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/submit" />","Button","android.widget.Button","class",0 ,"Drawable Resources","Nine-Patch","
A NinePatch
is a PNG image in which you can define stretchable regions that Android scales when content within the View exceeds the normal image bounds. You typically assign this type of image as the background of a View that has at least one dimension set to "wrap_content"
, and when the View grows to accomodate the content, the Nine-Patch image is also scaled to match the size of the View. An example use of a Nine-Patch image is the background used by Android's standard Button
widget, which must stretch to accommodate the text (or image) inside the button.
Same as with a normal bitmap, you can reference a Nine-Patch file directly or from a resource defined by XML.
For a complete discussion about how to create a Nine-Patch file with stretchable regions, see the 2D Graphics document.
","Button","android.widget.Button","class",0 ,"Drawable Resources","State List","A StateListDrawable
is a drawable object defined in XML that uses a several different images to represent the same graphic, depending on the state of the object. For example, a Button
widget can exist in one of several different states (pressed, focused, or niether) and, using a state list drawable, you can provide a different background image for each state.
You can describe the state list in an XML file. Each graphic is represented by an <item>
element inside a single <selector>
element. Each <item>
uses various attributes to describe the state in which it should be used as the graphic for the drawable.
During each state change, the state list is traversed top to bottom and the first item that matches the current state is used!the selection is not based on the "best match," but simply the first item that meets the minimum criteria of the state.
res/drawable/filename.xml
StateListDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?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>
res/drawable/button.xml
:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/button_pressed" /> <!-- pressed --> <item android:state_focused="true" android:drawable="@drawable/button_focused" /> <!-- focused --> <item android:state_hovered="true" android:drawable="@drawable/button_focused" /> <!-- hovered --> <item android:drawable="@drawable/button_normal" /> <!-- default --> </selector>
This layout XML applies the state list drawable to a Button:
<Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/button" />
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android
package name. For example, Android provides a layout resource you can use for list items in a ListAdapter
:
setListAdapter
(newArrayAdapter
<String>(this, android.R.layout.simple_list_item_1, myarray));
In this example, simple_list_item_1
is a layout resource defined by the platform for items in a ListView
. You can use this instead of creating your own layout for list items. For more information, see the List View developer guide.
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android
package name. For example, Android provides a layout resource you can use for list items in a ListAdapter
:
setListAdapter
(newArrayAdapter
<String>(this, android.R.layout.simple_list_item_1, myarray));
In this example, simple_list_item_1
is a layout resource defined by the platform for items in a ListView
. You can use this instead of creating your own layout for list items. For more information, see the List View developer guide.
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android
package name. For example, Android provides a layout resource you can use for list items in a ListAdapter
:
setListAdapter
(newArrayAdapter
<String>(this, android.R.layout.simple_list_item_1, myarray));
In this example, simple_list_item_1
is a layout resource defined by the platform for items in a ListView
. You can use this instead of creating your own layout for list items. For more information, see the List View developer guide.
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android
package name. For example, Android provides a layout resource you can use for list items in a ListAdapter
:
setListAdapter
(newArrayAdapter
<String>(this, android.R.layout.simple_list_item_1, myarray));
In this example, simple_list_item_1
is a layout resource defined by the platform for items in a ListView
. You can use this instead of creating your own layout for list items. For more information, see the List View developer guide.
Android contains a number of standard resources, such as styles, themes, and layouts. To access these resource, qualify your resource reference with the android
package name. For example, Android provides a layout resource you can use for list items in a ListAdapter
:
setListAdapter
(newArrayAdapter
<String>(this, android.R.layout.simple_list_item_1, myarray));
In this example, simple_list_item_1
is a layout resource defined by the platform for items in a ListView
. You can use this instead of creating your own layout for list items. For more information, see the List View developer guide.
An animation resource can define one of two types of animations:
Animator
.
There are two types of animations that you can do with the view animation framework:
Animation
AnimationDrawable
.An animation resource can define one of two types of animations:
Animator
.
There are two types of animations that you can do with the view animation framework:
Animation
AnimationDrawable
.An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation resource can define one of two types of animations:
Animator
.
There are two types of animations that you can do with the view animation framework:
Animation
AnimationDrawable
.An animation defined in XML that shows a sequence of images in order (like a film).
res/drawable/filename.xml
AnimationDrawable
.
R.drawable.filename
@[package:]drawable.filename
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
res/anim/rocket.xml
:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> </animation-list>
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image); rocketImage.setBackgroundResource
(R.drawable.rocket_thrust); rocketAnimation = (AnimationDrawable) rocketImage.getBackground()
; rocketAnimation.start()
;
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
An animation defined in XML that modifies properties of the target object, such as background color or alpha value, over a set amount of time.
res/animator/filename.xml
ValueAnimator
,
ObjectAnimator
, or
AnimatorSet
.
R.animator.filename
@[package:]animator/filename
<set android:ordering=["together" | "sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <animator android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <set> ... </set> </set>
The file must have a single root element: either <set>
, <objectAnimator>
, or <valueAnimator>
. You can group animation elements together inside the <set>
element, including other <set>
elements.
res/animator/property_animator.xml
:
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
In order to run this animation, you must inflate the XML resources in your code to an AnimatorSet
object, and then set the target objects for all of the animations before starting the animation set. Calling setTarget()
sets a single target object for all children of the AnimatorSet
as a convenience. The following code shows how to do this:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
An animation defined in XML that modifies properties of the target object, such as background color or alpha value, over a set amount of time.
res/animator/filename.xml
ValueAnimator
,
ObjectAnimator
, or
AnimatorSet
.
R.animator.filename
@[package:]animator/filename
<set android:ordering=["together" | "sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <animator android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <set> ... </set> </set>
The file must have a single root element: either <set>
, <objectAnimator>
, or <valueAnimator>
. You can group animation elements together inside the <set>
element, including other <set>
elements.
res/animator/property_animator.xml
:
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
In order to run this animation, you must inflate the XML resources in your code to an AnimatorSet
object, and then set the target objects for all of the animations before starting the animation set. Calling setTarget()
sets a single target object for all children of the AnimatorSet
as a convenience. The following code shows how to do this:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
An animation defined in XML that modifies properties of the target object, such as background color or alpha value, over a set amount of time.
res/animator/filename.xml
ValueAnimator
,
ObjectAnimator
, or
AnimatorSet
.
R.animator.filename
@[package:]animator/filename
<set android:ordering=["together" | "sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <animator android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <set> ... </set> </set>
The file must have a single root element: either <set>
, <objectAnimator>
, or <valueAnimator>
. You can group animation elements together inside the <set>
element, including other <set>
elements.
res/animator/property_animator.xml
:
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
In order to run this animation, you must inflate the XML resources in your code to an AnimatorSet
object, and then set the target objects for all of the animations before starting the animation set. Calling setTarget()
sets a single target object for all children of the AnimatorSet
as a convenience. The following code shows how to do this:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
An animation defined in XML that modifies properties of the target object, such as background color or alpha value, over a set amount of time.
res/animator/filename.xml
ValueAnimator
,
ObjectAnimator
, or
AnimatorSet
.
R.animator.filename
@[package:]animator/filename
<set android:ordering=["together" | "sequentially"]> <objectAnimator android:propertyName="string" android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <animator android:duration="int" android:valueFrom="float | int | color" android:valueTo="float | int | color" android:startOffset="int" android:repeatCount="int" android:repeatMode=["repeat" | "reverse"] android:valueType=["intType" | "floatType"]/> <set> ... </set> </set>
The file must have a single root element: either <set>
, <objectAnimator>
, or <valueAnimator>
. You can group animation elements together inside the <set>
element, including other <set>
elements.
res/animator/property_animator.xml
:
<set android:ordering="sequentially"> <set> <objectAnimator android:propertyName="x" android:duration="500" android:valueTo="400" android:valueType="intType"/> <objectAnimator android:propertyName="y" android:duration="500" android:valueTo="300" android:valueType="intType"/> </set> <objectAnimator android:propertyName="alpha" android:duration="500" android:valueTo="1f"/> </set>
In order to run this animation, you must inflate the XML resources in your code to an AnimatorSet
object, and then set the target objects for all of the animations before starting the animation set. Calling setTarget()
sets a single target object for all children of the AnimatorSet
as a convenience. The following code shows how to do this:
AnimatorSet set = (AnimatorSet) AnimatorInflater.loadAnimator(myContext, R.anim.property_animator); set.setTarget(myObject); set.start();
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","Interpolator","android.view.animation.Interpolator","class",1 ,"Tween animation","Custom interpolators","
If you're not satisfied with the interpolators provided by the platform (listed in the table above), you can create a custom interpolator resource with modified attributes. For example, you can adjust the rate of acceleration for the AnticipateInterpolator
, or adjust the number of cycles for the CycleInterpolator
. In order to do so, you need to create your own interpolator resource in an XML file.
res/anim/filename.xml
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
If you don't apply any attributes, then your interpolator will function exactly the same as those provided by the platform (listed in the table above).
Interpolator
implementation, when defined in XML, begins its name in lowercase.
XML file saved at res/anim/my_overshoot_interpolator.xml
:
<?xml version="1.0" encoding="utf-8"?> <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:tension="7.0" />
This animation XML will apply the interpolator:
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/my_overshoot_interpolator" android:fromXScale="1.0" android:toXScale="3.0" android:fromYScale="1.0" android:toYScale="3.0" android:pivotX="50%" android:pivotY="50%" android:duration="700" />
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation defined in XML that shows a sequence of images in order (like a film).
res/drawable/filename.xml
AnimationDrawable
.
R.drawable.filename
@[package:]drawable.filename
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot=["true" | "false"] > <item android:drawable="@[package:]drawable/drawable_resource_name" android:duration="integer" /> </animation-list>
res/anim/rocket.xml
:
<?xml version="1.0" encoding="utf-8"?> <animation-list xmlns:android="http://schemas.android.com/apk/res/android" android:oneshot="false"> <item android:drawable="@drawable/rocket_thrust1" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust2" android:duration="200" /> <item android:drawable="@drawable/rocket_thrust3" android:duration="200" /> </animation-list>
ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image); rocketImage.setBackgroundResource
(R.drawable.rocket_thrust); rocketAnimation = (AnimationDrawable) rocketImage.getBackground()
; rocketAnimation.start()
;
A LayerDrawable
is a drawable object that manages an array of other drawables. Each drawable in the list is drawn in the order of the list!the last drawable in the list is drawn on top.
Each drawable is represented by an <item>
element inside a single <layer-list>
element.
res/drawable/filename.xml
LayerDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </layer-list>
res/drawable/layers.xml
:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:src="@drawable/android_red" android:gravity="center" /> </item> <item android:top="10dp" android:left="10dp"> <bitmap android:src="@drawable/android_green" android:gravity="center" /> </item> <item android:top="20dp" android:left="20dp"> <bitmap android:src="@drawable/android_blue" android:gravity="center" /> </item> </layer-list>
Notice that this example uses a nested <bitmap>
element to define the drawable resource for each item with a "center" gravity. This ensures that none of the images are scaled to fit the size of the container, due to resizing caused by the offset images.
This layout XML applies the drawable to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/layers" />
The result is a stack of increasingly offset images:
A Drawable that manages a number of alternate Drawables, each assigned a maximum numerical value. Setting the level value of the drawable with setLevel()
loads the drawable resource in the level list that has a android:maxLevel
value greater than or equal to the value passed to the method.
res/drawable/filename.xml
LevelListDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/drawable_resource" android:maxLevel="integer" android:minLevel="integer" /> </level-list>
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/status_off" android:maxLevel="0" /> <item android:drawable="@drawable/status_on" android:maxLevel="1" /> </level-list>
Once this is applied to a View
, the level can be changed with setLevel()
or setImageLevel()
.
A TransitionDrawable
is a drawable object that can cross-fade between the two drawable resources.
Each drawable is represented by an <item>
element inside a single <transition>
element. No more than two items are supported. To transition forward, call startTransition()
. To transition backward, call reverseTransition()
.
res/drawable/filename.xml
TransitionDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </transition>
res/drawable/transition.xml
:
<?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>
This layout XML applies the drawable to a View:
<ImageButton android:id="@+id/button" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/transition" />
And the following code performs a 500ms transition from the first item to the second:
ImageButton button = (ImageButton) findViewById(R.id.button); TransitionDrawable drawable = (TransitionDrawable) button.getDrawable(); drawable.startTransition(500);
A unique resource ID defined in XML. Using the name you provide in the <item>
element, the Android developer tools create a unique integer in your project's R.java
class, which you can use as an identifier for an application resources (for example, a View
in your UI layout) or a unique integer for use in your application code (for example, as an ID for a dialog or a result code).
Note: An ID is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine ID resources with other simple resources in the one XML file, under one <resources>
element. Also, remember that an ID resources does not reference an actual resource item; it is simply a unique ID that you can attach to other resources or use as a unique integer in your application.
res/values/filename.xml
R.id.name
@[package:]id/name
<?xml version="1.0" encoding="utf-8"?> <resources> <item type="id" name="id_name" /> </resources>
XML file saved at res/values/ids.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <item type="id" name="button_ok" /> <item type="id" name="dialog_exit" /> </resources>
Then, this layout snippet uses the "button_ok" ID for a Button widget:
<Button android:id="@id/button_ok" style="@style/button_style" />
Notice that the android:id
value does not include the plus sign in the ID reference, because the ID already exists, as defined in the ids.xml
example above. (When you specify an ID to an XML resource using the plus sign!in the format android:id="@+id/name"
!it means that the "name" ID does not exist and should be created.)
As another example, the following code snippet uses the "dialog_exit" ID as a unique identifier for a dialog:
showDialog
(R.id.dialog_exit);
In the same application, the "dialog_exit" ID is compared when creating a dialog:
protected Dialog onCreateDialog(int)
(int id) {
Dialog dialog;
switch(id) {
case R.id.dialog_exit:
...
break;
default:
dialog = null;
}
return dialog;
}
If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle
that the system saves for you with the onSaveInstanceState()
callback!it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object
when your activity is restarted due to a configuration change.
To retain an object during a runtime configuration change:
onRetainNonConfigurationInstance()
method to return the object you would like to retain.getLastNonConfigurationInstance()
to recover your object.When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance()
between the onStop()
and onDestroy()
callbacks. In your implementation of onRetainNonConfigurationInstance()
, you can return any Object
that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance()
to return an object carrying your data and then retrieve the data when your activity starts again with getLastNonConfigurationInstance()
. For example:
@Override public Object onRetainNonConfigurationInstance() { final MyDataObject data = collectMyLoadedData(); return data; }
Caution: While you can return any object, you should never pass an object that is tied to the Activity
, such as a Drawable
, an Adapter
, a View
or any other object that's associated with a Context
. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)
Then retrieve the data when your activity starts again:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); if (data == null) { data = loadMyData(); } ... }
In this case, getLastNonConfigurationInstance()
returns the data saved by onRetainNonConfigurationInstance()
. If data
is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An animation defined in XML that performs transitions such as rotating, fading, moving, and stretching on a graphic.
res/anim/filename.xml
Animation
.
R.anim.filename
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@[package:]anim/interpolator_resource" android:shareInterpolator=["true" | "false"] > <alpha android:fromAlpha="float" android:toAlpha="float" /> <scale android:fromXScale="float" android:toXScale="float" android:fromYScale="float" android:toYScale="float" android:pivotX="float" android:pivotY="float" /> <translate android:fromXDelta="float" android:toXDelta="float" android:fromYDelta="float" android:toYDelta="float" /> <rotate android:fromDegrees="float" android:toDegrees="float" android:pivotX="float" android:pivotY="float" /> <set> ... </set> </set>
The file must have a single root element: either an <alpha>
, <scale>
, <translate>
, <rotate>
, or <set>
element that holds a group (or groups) of other animation elements (even nested <set>
elements).
res/anim/hyperspace_jump.xml
:
<set xmlns:android="http://schemas.android.com/apk/res/android" android:shareInterpolator="false"> <scale android:interpolator="@android:anim/accelerate_decelerate_interpolator" android:fromXScale="1.0" android:toXScale="1.4" android:fromYScale="1.0" android:toYScale="0.6" android:pivotX="50%" android:pivotY="50%" android:fillAfter="false" android:duration="700" /> <set android:interpolator="@android:anim/accelerate_interpolator" android:startOffset="700"> <scale android:fromXScale="1.4" android:toXScale="0.0" android:fromYScale="0.6" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> <rotate android:fromDegrees="0" android:toDegrees="-45" android:toYScale="0.0" android:pivotX="50%" android:pivotY="50%" android:duration="400" /> </set> </set>
This application code will apply the animation to an ImageView
and start the animation:
ImageView image = (ImageView) findViewById(R.id.image); Animation hyperspaceJump = AnimationUtils.loadAnimation
(this, R.anim.hyperspace_jump); image.startAnimation
(hyperspaceJump);
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","AccelerateDecelerateInterpolator","android.view.animation.AccelerateDecelerateInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","AnticipateInterpolator","android.view.animation.AnticipateInterpolator","class",0 ,"Tween animation","Custom interpolators","
If you're not satisfied with the interpolators provided by the platform (listed in the table above), you can create a custom interpolator resource with modified attributes. For example, you can adjust the rate of acceleration for the AnticipateInterpolator
, or adjust the number of cycles for the CycleInterpolator
. In order to do so, you need to create your own interpolator resource in an XML file.
res/anim/filename.xml
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
If you don't apply any attributes, then your interpolator will function exactly the same as those provided by the platform (listed in the table above).
Interpolator
implementation, when defined in XML, begins its name in lowercase.
XML file saved at res/anim/my_overshoot_interpolator.xml
:
<?xml version="1.0" encoding="utf-8"?> <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:tension="7.0" />
This animation XML will apply the interpolator:
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/my_overshoot_interpolator" android:fromXScale="1.0" android:toXScale="3.0" android:fromYScale="1.0" android:toYScale="3.0" android:pivotX="50%" android:pivotY="50%" android:duration="700" />
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","BounceInterpolator","android.view.animation.BounceInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","AnticipateOvershootInterpolator","android.view.animation.AnticipateOvershootInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","OvershootInterpolator","android.view.animation.OvershootInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","LinearInterpolator","android.view.animation.LinearInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","DecelerateInterpolator","android.view.animation.DecelerateInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","AccelerateInterpolator","android.view.animation.AccelerateInterpolator","class",0 ,"Tween animation","Interpolators","
An interpolator is an animation modifier defined in XML that affects the rate of change in an animation. This allows your existing animation effects to be accelerated, decelerated, repeated, bounced, etc.
An interpolator is applied to an animation element with the android:interpolator
attribute, the value of which is a reference to an interpolator resource.
All interpolators available in Android are subclasses of the Interpolator
class. For each interpolator class, Android includes a public resource you can reference in order to apply the interpolator to an animation using the android:interpolator
attribute. The following table specifies the resource to use for each interpolator:
Interpolator class | Resource ID |
---|---|
AccelerateDecelerateInterpolator |
@android:anim/accelerate_decelerate_interpolator |
AccelerateInterpolator |
@android:anim/accelerate_interpolator |
AnticipateInterpolator |
@android:anim/anticipate_interpolator |
AnticipateOvershootInterpolator |
@android:anim/anticipate_overshoot_interpolator |
BounceInterpolator |
@android:anim/bounce_interpolator |
CycleInterpolator |
@android:anim/cycle_interpolator |
DecelerateInterpolator |
@android:anim/decelerate_interpolator |
LinearInterpolator |
@android:anim/linear_interpolator |
OvershootInterpolator |
@android:anim/overshoot_interpolator |
Here's how you can apply one of these with the android:interpolator
attribute:
<set android:interpolator="@android:anim/accelerate_interpolator"> ... </set>","CycleInterpolator","android.view.animation.CycleInterpolator","class",0 ,"Tween animation","Custom interpolators","
If you're not satisfied with the interpolators provided by the platform (listed in the table above), you can create a custom interpolator resource with modified attributes. For example, you can adjust the rate of acceleration for the AnticipateInterpolator
, or adjust the number of cycles for the CycleInterpolator
. In order to do so, you need to create your own interpolator resource in an XML file.
res/anim/filename.xml
@[package:]anim/filename
<?xml version="1.0" encoding="utf-8"?> <InterpolatorName xmlns:android="http://schemas.android.com/apk/res/android" android:attribute_name="value" />
If you don't apply any attributes, then your interpolator will function exactly the same as those provided by the platform (listed in the table above).
Interpolator
implementation, when defined in XML, begins its name in lowercase.
XML file saved at res/anim/my_overshoot_interpolator.xml
:
<?xml version="1.0" encoding="utf-8"?> <overshootInterpolator xmlns:android="http://schemas.android.com/apk/res/android" android:tension="7.0" />
This animation XML will apply the interpolator:
<scale xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@anim/my_overshoot_interpolator" android:fromXScale="1.0" android:toXScale="3.0" android:fromYScale="1.0" android:toYScale="3.0" android:pivotX="50%" android:pivotY="50%" android:duration="700" />
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A TransitionDrawable
is a drawable object that can cross-fade between the two drawable resources.
Each drawable is represented by an <item>
element inside a single <transition>
element. No more than two items are supported. To transition forward, call startTransition()
. To transition backward, call reverseTransition()
.
res/drawable/filename.xml
TransitionDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <transition xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </transition>
res/drawable/transition.xml
:
<?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>
This layout XML applies the drawable to a View:
<ImageButton android:id="@+id/button" android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/transition" />
And the following code performs a 500ms transition from the first item to the second:
ImageButton button = (ImageButton) findViewById(R.id.button); TransitionDrawable drawable = (TransitionDrawable) button.getDrawable(); drawable.startTransition(500);
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A LayerDrawable
is a drawable object that manages an array of other drawables. Each drawable in the list is drawn in the order of the list!the last drawable in the list is drawn on top.
Each drawable is represented by an <item>
element inside a single <layer-list>
element.
res/drawable/filename.xml
LayerDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@[package:]drawable/drawable_resource" android:id="@[+][package:]id/resource_name" android:top="dimension" android:right="dimension" android:bottom="dimension" android:left="dimension" /> </layer-list>
res/drawable/layers.xml
:
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <bitmap android:src="@drawable/android_red" android:gravity="center" /> </item> <item android:top="10dp" android:left="10dp"> <bitmap android:src="@drawable/android_green" android:gravity="center" /> </item> <item android:top="20dp" android:left="20dp"> <bitmap android:src="@drawable/android_blue" android:gravity="center" /> </item> </layer-list>
Notice that this example uses a nested <bitmap>
element to define the drawable resource for each item with a "center" gravity. This ensures that none of the images are scaled to fit the size of the container, due to resizing caused by the offset images.
This layout XML applies the drawable to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/layers" />
The result is a stack of increasingly offset images:
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
This is a generic shape defined in XML.
res/drawable/filename.xml
GradientDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>
res/drawable/gradient_box.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape>
This layout XML applies the shape drawable to a View:
<TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
This application code gets the shape drawable and applies it to a View:
Resources res =getResources()
; Drawable shape = res.getDrawable
(R.drawable.gradient_box); TextView tv = (TextView)findViewByID(R.id.textview); tv.setBackground(shape);
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A StateListDrawable
is a drawable object defined in XML that uses a several different images to represent the same graphic, depending on the state of the object. For example, a Button
widget can exist in one of several different states (pressed, focused, or niether) and, using a state list drawable, you can provide a different background image for each state.
You can describe the state list in an XML file. Each graphic is represented by an <item>
element inside a single <selector>
element. Each <item>
uses various attributes to describe the state in which it should be used as the graphic for the drawable.
During each state change, the state list is traversed top to bottom and the first item that matches the current state is used!the selection is not based on the "best match," but simply the first item that meets the minimum criteria of the state.
res/drawable/filename.xml
StateListDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?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>
res/drawable/button.xml
:
<?xml version="1.0" encoding="utf-8"?> <selector xmlns:android="http://schemas.android.com/apk/res/android"> <item android:state_pressed="true" android:drawable="@drawable/button_pressed" /> <!-- pressed --> <item android:state_focused="true" android:drawable="@drawable/button_focused" /> <!-- focused --> <item android:state_hovered="true" android:drawable="@drawable/button_focused" /> <!-- hovered --> <item android:drawable="@drawable/button_normal" /> <!-- default --> </selector>
This layout XML applies the state list drawable to a Button:
<Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/button" />
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A drawable defined in XML that clips another drawable based on this Drawable's current level. You can control how much the child drawable gets clipped in width and height based on the level, as well as a gravity to control where it is placed in its overall container. Most often used to implement things like progress bars.
res/drawable/filename.xml
ClipDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/drawable_resource" android:clipOrientation=["horizontal" | "vertical"] android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" | "fill_vertical" | "center_horizontal" | "fill_horizontal" | "center" | "fill" | "clip_vertical" | "clip_horizontal"] />
res/drawable/clip.xml
:
<?xml version="1.0" encoding="utf-8"?> <clip xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/android" android:clipOrientation="horizontal" android:gravity="left" />
The following layout XML applies the clip drawable to a View:
<ImageView android:id="@+id/image" android:background="@drawable/clip" android:layout_height="wrap_content" android:layout_width="wrap_content" />
The following code gets the drawable and increases the amount of clipping in order to progressively reveal the image:
ImageView imageview = (ImageView) findViewById(R.id.image); ClipDrawable drawable = (ClipDrawable) imageview.getDrawable(); drawable.setLevel(drawable.getLevel() + 1000);
Increasing the level reduces the amount of clipping and slowly reveals the image. Here it is at a level of 7000:
Note: The default level is 0, which is fully clipped so the image is not visible. When the level is 10,000, the image is not clipped and completely visible.
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A Drawable that manages a number of alternate Drawables, each assigned a maximum numerical value. Setting the level value of the drawable with setLevel()
loads the drawable resource in the level list that has a android:maxLevel
value greater than or equal to the value passed to the method.
res/drawable/filename.xml
LevelListDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/drawable_resource" android:maxLevel="integer" android:minLevel="integer" /> </level-list>
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/status_off" android:maxLevel="0" /> <item android:drawable="@drawable/status_on" android:maxLevel="1" /> </level-list>
Once this is applied to a View
, the level can be changed with setLevel()
or setImageLevel()
.
This is a generic shape defined in XML.
res/drawable/filename.xml
GradientDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>
res/drawable/gradient_box.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape>
This layout XML applies the shape drawable to a View:
<TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
This application code gets the shape drawable and applies it to a View:
Resources res =getResources()
; Drawable shape = res.getDrawable
(R.drawable.gradient_box); TextView tv = (TextView)findViewByID(R.id.textview); tv.setBackground(shape);
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
res/drawable/filename.9.png
NinePatchDrawable
.
R.drawable.filename
@[package:]drawable/filename
res/drawable/myninepatch.9.png
, this layout XML applies the Nine-Patch to a View:
<Button android:layout_height="wrap_content" android:layout_width="wrap_content" android:background="@drawable/myninepatch" />
An XML Nine-Patch is a resource defined in XML that points to a Nine-Patch file. The XML can specify dithering for the image.
res/drawable/filename.xml
NinePatchDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@[package:]drawable/drawable_resource" android:dither=["true" | "false"] />
<?xml version="1.0" encoding="utf-8"?> <nine-patch xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/myninepatch" android:dither="false" />
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A bitmap file is a .png
, .jpg
, or .gif
file. Android creates a Drawable
resource for any of these files when you save them in the res/drawable/
directory.
res/drawable/filename.png
(
.png
,
.jpg
, or
.gif
)
BitmapDrawable
.
R.drawable.filename
@[package:]drawable/filename
res/drawable/myimage.png
, this layout XML applies the image to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/myimage" />
The following application code retrieves the image as a Drawable
:
Resources res =getResources()
; Drawable drawable = res.getDrawable
(R.drawable.myimage);
An XML bitmap is a resource defined in XML that points to a bitmap file. The effect is an alias for a raw bitmap file. The XML can specify additional properties for the bitmap such as dithering and tiling.
Note: You can use a <bitmap>
element as a child of an <item>
element. For example, when creating a state list or layer list, you can exclude the android:drawable
attribute from an <item>
element and nest a <bitmap>
inside it that defines the drawable item.
res/drawable/filename.xml
BitmapDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@[package:]drawable/drawable_resource" android:antialias=["true" | "false"] android:dither=["true" | "false"] android:filter=["true" | "false"] android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" | "fill_vertical" | "center_horizontal" | "fill_horizontal" | "center" | "fill" | "clip_vertical" | "clip_horizontal"] android:mipMap=["true" | "false"] android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/icon" android:tileMode="repeat" />
A drawable resource is a general concept for a graphic that can be drawn to the screen and which you can retrieve with APIs such as getDrawable(int)
or apply to another XML resource with attributes such as android:drawable
and android:icon
. There are several different types of drawables:
.png
,
.jpg
, or
.gif
). Creates a
BitmapDrawable
.
.9.png
). Creates a
NinePatchDrawable
.
LayerDrawable
.
StateListDrawable
.
LevelListDrawable
.
TransitionDrawable
.
ClipDrawable
.
ScaleDrawable
ShapeDrawable
.
Also see the Animation Resource document for how to create an AnimationDrawable
.
Note: A color resource can also be used as a drawable in XML. For example, when creating a state list drawable, you can reference a color resource for the android:drawable
attribute (android:drawable="@color/green"
).
A drawable defined in XML that changes the size of another drawable based on its current level.
res/drawable/filename.xml
ScaleDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/drawable_resource" android:scaleGravity=["top" | "bottom" | "left" | "right" | "center_vertical" | "fill_vertical" | "center_horizontal" | "fill_horizontal" | "center" | "fill" | "clip_vertical" | "clip_horizontal"] android:scaleHeight="percentage" android:scaleWidth="percentage" />
<?xml version="1.0" encoding="utf-8"?> <scale xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/logo" android:scaleGravity="center_vertical|center_horizontal" android:scaleHeight="80%" android:scaleWidth="80%" />
A bitmap file is a .png
, .jpg
, or .gif
file. Android creates a Drawable
resource for any of these files when you save them in the res/drawable/
directory.
res/drawable/filename.png
(
.png
,
.jpg
, or
.gif
)
BitmapDrawable
.
R.drawable.filename
@[package:]drawable/filename
res/drawable/myimage.png
, this layout XML applies the image to a View:
<ImageView android:layout_height="wrap_content" android:layout_width="wrap_content" android:src="@drawable/myimage" />
The following application code retrieves the image as a Drawable
:
Resources res =getResources()
; Drawable drawable = res.getDrawable
(R.drawable.myimage);
A Drawable that manages a number of alternate Drawables, each assigned a maximum numerical value. Setting the level value of the drawable with setLevel()
loads the drawable resource in the level list that has a android:maxLevel
value greater than or equal to the value passed to the method.
res/drawable/filename.xml
LevelListDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/drawable_resource" android:maxLevel="integer" android:minLevel="integer" /> </level-list>
<?xml version="1.0" encoding="utf-8"?> <level-list xmlns:android="http://schemas.android.com/apk/res/android" > <item android:drawable="@drawable/status_off" android:maxLevel="0" /> <item android:drawable="@drawable/status_on" android:maxLevel="1" /> </level-list>
Once this is applied to a View
, the level can be changed with setLevel()
or setImageLevel()
.
If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle
that the system saves for you with the onSaveInstanceState()
callback!it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object
when your activity is restarted due to a configuration change.
To retain an object during a runtime configuration change:
onRetainNonConfigurationInstance()
method to return the object you would like to retain.getLastNonConfigurationInstance()
to recover your object.When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance()
between the onStop()
and onDestroy()
callbacks. In your implementation of onRetainNonConfigurationInstance()
, you can return any Object
that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance()
to return an object carrying your data and then retrieve the data when your activity starts again with getLastNonConfigurationInstance()
. For example:
@Override public Object onRetainNonConfigurationInstance() { final MyDataObject data = collectMyLoadedData(); return data; }
Caution: While you can return any object, you should never pass an object that is tied to the Activity
, such as a Drawable
, an Adapter
, a View
or any other object that's associated with a Context
. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)
Then retrieve the data when your activity starts again:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); if (data == null) { data = loadMyData(); } ... }
In this case, getLastNonConfigurationInstance()
returns the data saved by onRetainNonConfigurationInstance()
. If data
is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.
An XML bitmap is a resource defined in XML that points to a bitmap file. The effect is an alias for a raw bitmap file. The XML can specify additional properties for the bitmap such as dithering and tiling.
Note: You can use a <bitmap>
element as a child of an <item>
element. For example, when creating a state list or layer list, you can exclude the android:drawable
attribute from an <item>
element and nest a <bitmap>
inside it that defines the drawable item.
res/drawable/filename.xml
BitmapDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@[package:]drawable/drawable_resource" android:antialias=["true" | "false"] android:dither=["true" | "false"] android:filter=["true" | "false"] android:gravity=["top" | "bottom" | "left" | "right" | "center_vertical" | "fill_vertical" | "center_horizontal" | "fill_horizontal" | "center" | "fill" | "clip_vertical" | "clip_horizontal"] android:mipMap=["true" | "false"] android:tileMode=["disabled" | "clamp" | "repeat" | "mirror"] />
<?xml version="1.0" encoding="utf-8"?> <bitmap xmlns:android="http://schemas.android.com/apk/res/android" android:src="@drawable/icon" android:tileMode="repeat" />
A NinePatch
is a PNG image in which you can define stretchable regions that Android scales when content within the View exceeds the normal image bounds. You typically assign this type of image as the background of a View that has at least one dimension set to "wrap_content"
, and when the View grows to accomodate the content, the Nine-Patch image is also scaled to match the size of the View. An example use of a Nine-Patch image is the background used by Android's standard Button
widget, which must stretch to accommodate the text (or image) inside the button.
Same as with a normal bitmap, you can reference a Nine-Patch file directly or from a resource defined by XML.
For a complete discussion about how to create a Nine-Patch file with stretchable regions, see the 2D Graphics document.
","NinePatch","android.graphics.NinePatch","class",1 ,"Drawable Resources","Inset Drawable","A drawable defined in XML that insets another drawable by a specified distance. This is useful when a View needs a background that is smaller than the View's actual bounds.
res/drawable/filename.xml
InsetDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/drawable_resource" android:insetTop="dimension" android:insetRight="dimension" android:insetBottom="dimension" android:insetLeft="dimension" />
<?xml version="1.0" encoding="utf-8"?> <inset xmlns:android="http://schemas.android.com/apk/res/android" android:drawable="@drawable/background" android:insetTop="10dp" android:insetLeft="10dp" />
This is a generic shape defined in XML.
res/drawable/filename.xml
GradientDrawable
.
R.drawable.filename
@[package:]drawable/filename
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape=["rectangle" | "oval" | "line" | "ring"] > <corners android:radius="integer" android:topLeftRadius="integer" android:topRightRadius="integer" android:bottomLeftRadius="integer" android:bottomRightRadius="integer" /> <gradient android:angle="integer" android:centerX="integer" android:centerY="integer" android:centerColor="integer" android:endColor="color" android:gradientRadius="integer" android:startColor="color" android:type=["linear" | "radial" | "sweep"] android:useLevel=["true" | "false"] /> <padding android:left="integer" android:top="integer" android:right="integer" android:bottom="integer" /> <size android:width="integer" android:height="integer" /> <solid android:color="color" /> <stroke android:width="integer" android:color="color" android:dashWidth="integer" android:dashGap="integer" /> </shape>
res/drawable/gradient_box.xml
:
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http://schemas.android.com/apk/res/android" android:shape="rectangle"> <gradient android:startColor="#FFFF0000" android:endColor="#80FF00FF" android:angle="45"/> <padding android:left="7dp" android:top="7dp" android:right="7dp" android:bottom="7dp" /> <corners android:radius="8dp" /> </shape>
This layout XML applies the shape drawable to a View:
<TextView android:background="@drawable/gradient_box" android:layout_height="wrap_content" android:layout_width="wrap_content" />
This application code gets the shape drawable and applies it to a View:
Resources res =getResources()
; Drawable shape = res.getDrawable
(R.drawable.gradient_box); TextView tv = (TextView)findViewByID(R.id.textview); tv.setBackground(shape);
This page defines more types of resources you can externalize, including:
TypedArray
(which you can use for an array of drawables).
A TypedArray
defined in XML. You can use this to create an array of other resources, such as drawables. Note that the array is not required to be homogeneous, so you can create an array of mixed resource types, but you must be aware of what and where the data types are in the array so that you can properly obtain each item with the TypedArray
's get...()
methods.
Note: A typed array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine typed array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<array>
element's
name
will be used as the resource ID.
TypedArray
.
R.array.array_name
@[package:]array.array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="integer_array_name"> <item>resource</item> </array> </resources>
res/values/arrays.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <array name="icons"> <item>@drawable/home</item> <item>@drawable/settings</item> <item>@drawable/logout</item> </array> <array name="colors"> <item>#FFFF0000</item> <item>#FF00FF00</item> <item>#FF0000FF</item> </array> </resources>
This application code retrieves each array and then obtains the first entry in each array:
Resources res =getResources()
; TypedArray icons = res.obtainTypedArray
(R.array.icons); Drawable drawable = icons.getDrawable
(0); TypedArray colors = res.obtainTypedArray
(R.array.colors); int color = colors.getColor
(0,0);
You should place each type of resource in a specific subdirectory of your project's res/
directory. For example, here's the file hierarchy for a simple project:
MyProject/ src/ MyActivity.java res/ drawable/ icon.png layout/ main.xml info.xml values/ strings.xml
As you can see in this example, the res/
directory contains all the resources (in subdirectories): an image resource, two layout resources, and a string resource file. The resource directory names are important and are described in table 1.
Directory | Resource Type |
---|---|
animator/ |
XML files that define property animations. |
anim/ |
XML files that define tween animations. (Property animations can also be saved in this directory, but the animator/ directory is preferred for property animations to distinguish between the two types.) |
color/ |
XML files that define a state list of colors. See Color State List Resource |
drawable/ |
Bitmap files (
See Drawable Resources. |
layout/ |
XML files that define a user interface layout. See Layout Resource. |
menu/ |
XML files that define application menus, such as an Options Menu, Context Menu, or Sub Menu. See Menu Resource. |
raw/ |
Arbitrary files to save in their raw form. To open these resources with a raw However, if you need access to original file names and file hierarchy, you might consider saving some resources in the |
values/ |
XML files that contain simple values, such as strings, integers, and colors. Whereas XML resource files in other Because each resource is defined with its own XML element, you can name the file whatever you want and place different resource types in one file. However, for clarity, you might want to place unique resource types in different files. For example, here are some filename conventions for resources you can create in this directory:
See String Resources, Style Resource, and More Resource Types. |
xml/ |
Arbitrary XML files that can be read at runtime by calling Resources.getXML() . Various XML configuration files must be saved here, such as a searchable configuration.
|
Caution: Never save resource files directly inside the res/
directory!it will cause a compiler error.
For more information about certain types of resources, see the Resource Types documentation.
The resources that you save in the subdirectories defined in table 1 are your "default" resources. That is, these resources define the default design and content for your application. However, different types of Android-powered devices might call for different types of resources. For example, if a device has a larger than normal screen, then you should provide different layout resources that take advantage of the extra screen space. Or, if a device has a different language setting, then you should provide different string resources that translate the text in your user interface. To provide these different resources for different device configurations, you need to provide alternative resources, in addition to your default resources.
","InputStream","java.io.InputStream","class",0 ,"Providing Resources","Providing Alternative Resources","Almost every application should provide alternative resources to support specific device configurations. For instance, you should include alternative drawable resources for different screen densities and alternative string resources for different languages. At runtime, Android detects the current device configuration and loads the appropriate resources for your application.
To specify configuration-specific alternatives for a set of resources:
res/
named in the form <resources_name>-<config_qualifier>
.
<resources_name>
is the directory name of the corresponding default resources (defined in table 1).<qualifier>
is a name that specifies an individual configuration for which these resources are to be used (defined in table 2).You can append more than one <qualifier>
. Separate each one with a dash.
Caution: When appending multiple qualifiers, you must place them in the same order in which they are listed in table 2. If the qualifiers are ordered wrong, the resources are ignored.
For example, here are some default and alternative resources:
res/ drawable/ icon.png background.png drawable-hdpi/ icon.png background.png
The hdpi
qualifier indicates that the resources in that directory are for devices with a high-density screen. The images in each of these drawable directories are sized for a specific screen density, but the filenames are exactly the same. This way, the resource ID that you use to reference the icon.png
or background.png
image is always the same, but Android selects the version of each resource that best matches the current device, by comparing the device configuration information with the qualifiers in the resource directory name.
Android supports several configuration qualifiers and you can add multiple qualifiers to one directory name, by separating each qualifier with a dash. Table 2 lists the valid configuration qualifiers, in order of precedence!if you use multiple qualifiers for a resource directory, you must add them to the directory name in the order they are listed in the table.
Configuration | Qualifier Values | Description |
---|---|---|
MCC and MNC | Examples:mcc310
mcc208-mnc00 etc. |
The mobile country code (MCC), optionally followed by mobile network code (MNC) from the SIM card in the device. For example, If the device uses a radio connection (GSM phone), the MCC and MNC values come from the SIM card. You can also use the MCC alone (for example, to include country-specific legal resources in your application). If you need to specify based on the language only, then use the language and region qualifier instead (discussed next). If you decide to use the MCC and MNC qualifier, you should do so with care and test that it works as expected. Also see the configuration fields |
Language and region | Examples:en fr en-rUS fr-rFR fr-rCA etc. |
The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase " The codes are not case-sensitive; the This can change during the life of your application if the user changes his or her language in the system settings. See Handling Runtime Changes for information about how this can affect your application during runtime. See Localization for a complete guide to localizing your application for other languages. Also see the |
Layout Direction | ldrtl ldltr |
The layout direction of your application. This can apply to any resource such as layouts, drawables, or values. For example, if you want to provide some specific layout for the Arabic language and some generic layout for any other "right-to-left" language (like Persian or Hebrew) then you would have: res/ layout/ main.xml (Default layout) layout-ar/ main.xml (Specific layout for Arabic) layout-ldrtl/ main.xml (Any "right-to-left" language, except for Arabic, because the "ar" language qualifier has a higher precedence.) Note: To enable right-to-left layout features for your app, you must set Added in API level 17. |
smallestWidth | sw<N>dp Examples: sw320dp sw600dp sw720dp etc. |
The fundamental size of a screen, as indicated by the shortest dimension of the available screen area. Specifically, the device's smallestWidth is the shortest of the screen's available height and width (you may also think of it as the "smallest possible width" for the screen). You can use this qualifier to ensure that, regardless of the screen's current orientation, your application has at least For example, if your layout requires that its smallest dimension of screen area be at least 600 dp at all times, then you can use this qualifer to create the layout resources, The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actual screen size, because those are screen pixels not available for your UI. Thus, the value you use should be the actual smallest dimension required by your layout (usually, this value is the "smallest width" that your layout supports, regardless of the screen's current orientation). Some values you might use here for common screen sizes:
When your application provides multiple resource directories with different values for the smallestWidth qualifier, the system uses the one closest to (without exceeding) the device's smallestWidth. Added in API level 13. Also see the For more information about designing for different screens and using this qualifier, see the Supporting Multiple Screens developer guide. |
Available width | w<N>dp Examples: w720dp w1024dp etc. |
Specifies a minimum available screen width, in When your application provides multiple resource directories with different values for this configuration, the system uses the one closest to (without exceeding) the device's current screen width. The value here takes into account screen decorations, so if the device has some persistent UI elements on the left or right edge of the display, it uses a value for the width that is smaller than the real screen size, accounting for these UI elements and reducing the application's available space. Added in API level 13. Also see the For more information about designing for different screens and using this qualifier, see the Supporting Multiple Screens developer guide. |
Available height | h<N>dp Examples: h720dp h1024dp etc. |
Specifies a minimum available screen height, in "dp" units at which the resource should be used!defined by the When your application provides multiple resource directories with different values for this configuration, the system uses the one closest to (without exceeding) the device's current screen height. The value here takes into account screen decorations, so if the device has some persistent UI elements on the top or bottom edge of the display, it uses a value for the height that is smaller than the real screen size, accounting for these UI elements and reducing the application's available space. Screen decorations that are not fixed (such as a phone status bar that can be hidden when full screen) are not accounted for here, nor are window decorations like the title bar or action bar, so applications must be prepared to deal with a somewhat smaller space than they specify. Added in API level 13. Also see the For more information about designing for different screens and using this qualifier, see the Supporting Multiple Screens developer guide. |
Screen size | small normal large xlarge |
Note: Using a size qualifier does not imply that the resources are only for screens of that size. If you do not provide alternative resources with qualifiers that better match the current device configuration, the system may use whichever resources are the best match. Caution: If all your resources use a size qualifier that is larger than the current screen, the system will not use them and your application will crash at runtime (for example, if all layout resources are tagged with the Added in API level 4. See Supporting Multiple Screens for more information. Also see the |
Screen aspect | long notlong |
Added in API level 4. This is based purely on the aspect ratio of the screen (a "long" screen is wider). This is not related to the screen orientation. Also see the |
Screen orientation | port land
|
This can change during the life of your application if the user rotates the screen. See Handling Runtime Changes for information about how this affects your application during runtime. Also see the |
UI mode | car desk television |
Added in API level 8, television added in API 13. For information about how your app can respond when the device is inserted into or removed from a dock, read Determining and Monitoring the Docking State and Type. This can change during the life of your application if the user places the device in a dock. You can enable or disable some of these modes using |
Night mode | night notnight |
Added in API level 8. This can change during the life of your application if night mode is left in auto mode (default), in which case the mode changes based on the time of day. You can enable or disable this mode using |
Screen pixel density (dpi) | ldpi mdpi hdpi xhdpi nodpi tvdpi |
There is a 3:4:6:8 scaling ratio between the four primary densities (ignoring the tvdpi density). So, a 9x9 bitmap in ldpi is 12x12 in mdpi, 18x18 in hdpi and 24x24 in xhdpi. If you decide that your image resources don't look good enough on a television or other certain devices and want to try tvdpi resources, the scaling factor is 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi. Note: Using a density qualifier does not imply that the resources are only for screens of that density. If you do not provide alternative resources with qualifiers that better match the current device configuration, the system may use whichever resources are the best match. See Supporting Multiple Screens for more information about how to handle different screen densities and how Android might scale your bitmaps to fit the current density. |
Touchscreen type | notouch finger |
Also see the |
Keyboard availability | keysexposed keyshidden keyssoft |
If you provide This can change during the life of your application if the user opens a hardware keyboard. See Handling Runtime Changes for information about how this affects your application during runtime. Also see the configuration fields |
Primary text input method | nokeys qwerty 12key |
Also see the |
Navigation key availability | navexposed navhidden |
This can change during the life of your application if the user reveals the navigation keys. See Handling Runtime Changes for information about how this affects your application during runtime. Also see the |
Primary non-touch navigation method | nonav dpad trackball wheel |
Also see the |
Platform Version (API level) | Examples:v3 v4 v7 etc. |
The API level supported by the device. For example, |
Note: Some configuration qualifiers have been added since Android 1.0, so not all versions of Android support all the qualifiers. Using a new qualifier implicitly adds the platform version qualifier so that older devices are sure to ignore it. For example, using a w600dp
qualifier will automatically include the v13
qualifier, because the available-width qualifier was new in API level 13. To avoid any issues, always include a set of default resources (a set of resources with no qualifiers). For more information, see the section about Providing the Best Device Compatibility with Resources.
Almost every application should provide alternative resources to support specific device configurations. For instance, you should include alternative drawable resources for different screen densities and alternative string resources for different languages. At runtime, Android detects the current device configuration and loads the appropriate resources for your application.
To specify configuration-specific alternatives for a set of resources:
res/
named in the form <resources_name>-<config_qualifier>
.
<resources_name>
is the directory name of the corresponding default resources (defined in table 1).<qualifier>
is a name that specifies an individual configuration for which these resources are to be used (defined in table 2).You can append more than one <qualifier>
. Separate each one with a dash.
Caution: When appending multiple qualifiers, you must place them in the same order in which they are listed in table 2. If the qualifiers are ordered wrong, the resources are ignored.
For example, here are some default and alternative resources:
res/ drawable/ icon.png background.png drawable-hdpi/ icon.png background.png
The hdpi
qualifier indicates that the resources in that directory are for devices with a high-density screen. The images in each of these drawable directories are sized for a specific screen density, but the filenames are exactly the same. This way, the resource ID that you use to reference the icon.png
or background.png
image is always the same, but Android selects the version of each resource that best matches the current device, by comparing the device configuration information with the qualifiers in the resource directory name.
Android supports several configuration qualifiers and you can add multiple qualifiers to one directory name, by separating each qualifier with a dash. Table 2 lists the valid configuration qualifiers, in order of precedence!if you use multiple qualifiers for a resource directory, you must add them to the directory name in the order they are listed in the table.
Configuration | Qualifier Values | Description |
---|---|---|
MCC and MNC | Examples:mcc310
mcc208-mnc00 etc. |
The mobile country code (MCC), optionally followed by mobile network code (MNC) from the SIM card in the device. For example, If the device uses a radio connection (GSM phone), the MCC and MNC values come from the SIM card. You can also use the MCC alone (for example, to include country-specific legal resources in your application). If you need to specify based on the language only, then use the language and region qualifier instead (discussed next). If you decide to use the MCC and MNC qualifier, you should do so with care and test that it works as expected. Also see the configuration fields |
Language and region | Examples:en fr en-rUS fr-rFR fr-rCA etc. |
The language is defined by a two-letter ISO 639-1 language code, optionally followed by a two letter ISO 3166-1-alpha-2 region code (preceded by lowercase " The codes are not case-sensitive; the This can change during the life of your application if the user changes his or her language in the system settings. See Handling Runtime Changes for information about how this can affect your application during runtime. See Localization for a complete guide to localizing your application for other languages. Also see the |
Layout Direction | ldrtl ldltr |
The layout direction of your application. This can apply to any resource such as layouts, drawables, or values. For example, if you want to provide some specific layout for the Arabic language and some generic layout for any other "right-to-left" language (like Persian or Hebrew) then you would have: res/ layout/ main.xml (Default layout) layout-ar/ main.xml (Specific layout for Arabic) layout-ldrtl/ main.xml (Any "right-to-left" language, except for Arabic, because the "ar" language qualifier has a higher precedence.) Note: To enable right-to-left layout features for your app, you must set Added in API level 17. |
smallestWidth | sw<N>dp Examples: sw320dp sw600dp sw720dp etc. |
The fundamental size of a screen, as indicated by the shortest dimension of the available screen area. Specifically, the device's smallestWidth is the shortest of the screen's available height and width (you may also think of it as the "smallest possible width" for the screen). You can use this qualifier to ensure that, regardless of the screen's current orientation, your application has at least For example, if your layout requires that its smallest dimension of screen area be at least 600 dp at all times, then you can use this qualifer to create the layout resources, The smallestWidth of a device takes into account screen decorations and system UI. For example, if the device has some persistent UI elements on the screen that account for space along the axis of the smallestWidth, the system declares the smallestWidth to be smaller than the actual screen size, because those are screen pixels not available for your UI. Thus, the value you use should be the actual smallest dimension required by your layout (usually, this value is the "smallest width" that your layout supports, regardless of the screen's current orientation). Some values you might use here for common screen sizes:
When your application provides multiple resource directories with different values for the smallestWidth qualifier, the system uses the one closest to (without exceeding) the device's smallestWidth. Added in API level 13. Also see the For more information about designing for different screens and using this qualifier, see the Supporting Multiple Screens developer guide. |
Available width | w<N>dp Examples: w720dp w1024dp etc. |
Specifies a minimum available screen width, in When your application provides multiple resource directories with different values for this configuration, the system uses the one closest to (without exceeding) the device's current screen width. The value here takes into account screen decorations, so if the device has some persistent UI elements on the left or right edge of the display, it uses a value for the width that is smaller than the real screen size, accounting for these UI elements and reducing the application's available space. Added in API level 13. Also see the For more information about designing for different screens and using this qualifier, see the Supporting Multiple Screens developer guide. |
Available height | h<N>dp Examples: h720dp h1024dp etc. |
Specifies a minimum available screen height, in "dp" units at which the resource should be used!defined by the When your application provides multiple resource directories with different values for this configuration, the system uses the one closest to (without exceeding) the device's current screen height. The value here takes into account screen decorations, so if the device has some persistent UI elements on the top or bottom edge of the display, it uses a value for the height that is smaller than the real screen size, accounting for these UI elements and reducing the application's available space. Screen decorations that are not fixed (such as a phone status bar that can be hidden when full screen) are not accounted for here, nor are window decorations like the title bar or action bar, so applications must be prepared to deal with a somewhat smaller space than they specify. Added in API level 13. Also see the For more information about designing for different screens and using this qualifier, see the Supporting Multiple Screens developer guide. |
Screen size | small normal large xlarge |
Note: Using a size qualifier does not imply that the resources are only for screens of that size. If you do not provide alternative resources with qualifiers that better match the current device configuration, the system may use whichever resources are the best match. Caution: If all your resources use a size qualifier that is larger than the current screen, the system will not use them and your application will crash at runtime (for example, if all layout resources are tagged with the Added in API level 4. See Supporting Multiple Screens for more information. Also see the |
Screen aspect | long notlong |
Added in API level 4. This is based purely on the aspect ratio of the screen (a "long" screen is wider). This is not related to the screen orientation. Also see the |
Screen orientation | port land
|
This can change during the life of your application if the user rotates the screen. See Handling Runtime Changes for information about how this affects your application during runtime. Also see the |
UI mode | car desk television |
Added in API level 8, television added in API 13. For information about how your app can respond when the device is inserted into or removed from a dock, read Determining and Monitoring the Docking State and Type. This can change during the life of your application if the user places the device in a dock. You can enable or disable some of these modes using |
Night mode | night notnight |
Added in API level 8. This can change during the life of your application if night mode is left in auto mode (default), in which case the mode changes based on the time of day. You can enable or disable this mode using |
Screen pixel density (dpi) | ldpi mdpi hdpi xhdpi nodpi tvdpi |
There is a 3:4:6:8 scaling ratio between the four primary densities (ignoring the tvdpi density). So, a 9x9 bitmap in ldpi is 12x12 in mdpi, 18x18 in hdpi and 24x24 in xhdpi. If you decide that your image resources don't look good enough on a television or other certain devices and want to try tvdpi resources, the scaling factor is 1.33*mdpi. For example, a 100px x 100px image for mdpi screens should be 133px x 133px for tvdpi. Note: Using a density qualifier does not imply that the resources are only for screens of that density. If you do not provide alternative resources with qualifiers that better match the current device configuration, the system may use whichever resources are the best match. See Supporting Multiple Screens for more information about how to handle different screen densities and how Android might scale your bitmaps to fit the current density. |
Touchscreen type | notouch finger |
Also see the |
Keyboard availability | keysexposed keyshidden keyssoft |
If you provide This can change during the life of your application if the user opens a hardware keyboard. See Handling Runtime Changes for information about how this affects your application during runtime. Also see the configuration fields |
Primary text input method | nokeys qwerty 12key |
Also see the |
Navigation key availability | navexposed navhidden |
This can change during the life of your application if the user reveals the navigation keys. See Handling Runtime Changes for information about how this affects your application during runtime. Also see the |
Primary non-touch navigation method | nonav dpad trackball wheel |
Also see the |
Platform Version (API level) | Examples:v3 v4 v7 etc. |
The API level supported by the device. For example, |
Note: Some configuration qualifiers have been added since Android 1.0, so not all versions of Android support all the qualifiers. Using a new qualifier implicitly adds the platform version qualifier so that older devices are sure to ignore it. For example, using a w600dp
qualifier will automatically include the v13
qualifier, because the available-width qualifier was new in API level 13. To avoid any issues, always include a set of default resources (a set of resources with no qualifiers). For more information, see the section about Providing the Best Device Compatibility with Resources.
If your application doesn't need to update resources during a specific configuration change and you have a performance limitation that requires you to avoid the activity restart, then you can declare that your activity handles the configuration change itself, which prevents the system from restarting your activity.
Note: Handling the configuration change yourself can make it much more difficult to use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
To declare that your activity handles a configuration change, edit the appropriate <activity>
element in your manifest file to include the android:configChanges
attribute with a value that represents the configuration you want to handle. Possible values are listed in the documentation for the android:configChanges
attribute (the most commonly used values are "orientation"
to prevent restarts when the screen orientation changes and "keyboardHidden"
to prevent restarts when the keyboard availability changes). You can declare multiple configuration values in the attribute by separating them with a pipe |
character.
For example, the following manifest code declares an activity that handles both the screen orientation change and keyboard availability change:
<activity android:name=".MyActivity" android:configChanges="orientation|keyboardHidden" android:label="@string/app_name">
Now, when one of these configurations change, MyActivity
does not restart. Instead, the MyActivity
receives a call to onConfigurationChanged()
. This method is passed a Configuration
object that specifies the new device configuration. By reading fields in the Configuration
, you can determine the new configuration and make appropriate changes by updating the resources used in your interface. At the time this method is called, your activity's Resources
object is updated to return resources based on the new configuration, so you can easily reset elements of your UI without the system restarting your activity.
Caution: Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion
and targetSdkVersion
attributes), you must include the "screenSize"
value in addition to the "orientation"
value. That is, you must decalare android:configChanges="orientation|screenSize"
. However, if your application targets API level 12 or lower, then your activity always handles this configuration change itself (this configuration change does not restart your activity, even when running on an Android 3.2 or higher device).
For example, the following onConfigurationChanged()
implementation checks the current device orientation:
@Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // Checks the orientation of the screen if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) { Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show(); } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show(); } }
The Configuration
object represents all of the current configurations, not just the ones that have changed. Most of the time, you won't care exactly how the configuration has changed and can simply re-assign all your resources that provide alternatives to the configuration that you're handling. For example, because the Resources
object is now updated, you can reset any ImageView
s with setImageResource()
and the appropriate resource for the new configuration is used (as described in Providing Resources).
Notice that the values from the Configuration
fields are integers that are matched to specific constants from the Configuration
class. For documentation about which constants to use with each field, refer to the appropriate field in the Configuration
reference.
Remember: When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during onConfigurationChanged()
.
If you don't need to update your application based on these configuration changes, you can instead not implement onConfigurationChanged()
. In which case, all of the resources used before the configuration change are still used and you've only avoided the restart of your activity. However, your application should always be able to shutdown and restart with its previous state intact, so you should not consider this technique an escape from retaining your state during normal activity lifecycle. Not only because there are other configuration changes that you cannot prevent from restarting your application, but also because you should handle events such as when the user leaves your application and it gets destroyed before the user returns to it.
For more about which configuration changes you can handle in your activity, see the android:configChanges
documentation and the Configuration
class.
Some device configurations can change during runtime (such as screen orientation, keyboard availability, and language). When such a change occurs, Android restarts the running Activity
(onDestroy()
is called, followed by onCreate()
). The restart behavior is designed to help your application adapt to new configurations by automatically reloading your application with alternative resources that match the new device configuration.
To properly handle a restart, it is important that your activity restores its previous state through the normal Activity lifecycle, in which Android calls onSaveInstanceState()
before it destroys your activity so that you can save data about the application state. You can then restore the state during onCreate()
or onRestoreInstanceState()
.
To test that your application restarts itself with the application state intact, you should invoke configuration changes (such as changing the screen orientation) while performing various tasks in your application. Your application should be able to restart at any time without loss of user data or state in order to handle events such as configuration changes or when the user receives an incoming phone call and then returns to your application much later after your application process may have been destroyed. To learn how you can restore your activity state, read about the Activity lifecycle.
However, you might encounter a situation in which restarting your application and restoring significant amounts of data can be costly and create a poor user experience. In such a situation, you have two other options:
Allow your activity to restart when a configuration changes, but carry a stateful Object
to the new instance of your activity.
Prevent the system from restarting your activity during certain configuration changes, but receive a callback when the configurations do change, so that you can manually update your activity as necessary.
If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle
that the system saves for you with the onSaveInstanceState()
callback!it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object
when your activity is restarted due to a configuration change.
To retain an object during a runtime configuration change:
onRetainNonConfigurationInstance()
method to return the object you would like to retain.getLastNonConfigurationInstance()
to recover your object.When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance()
between the onStop()
and onDestroy()
callbacks. In your implementation of onRetainNonConfigurationInstance()
, you can return any Object
that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance()
to return an object carrying your data and then retrieve the data when your activity starts again with getLastNonConfigurationInstance()
. For example:
@Override public Object onRetainNonConfigurationInstance() { final MyDataObject data = collectMyLoadedData(); return data; }
Caution: While you can return any object, you should never pass an object that is tied to the Activity
, such as a Drawable
, an Adapter
, a View
or any other object that's associated with a Context
. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)
Then retrieve the data when your activity starts again:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); if (data == null) { data = loadMyData(); } ... }
In this case, getLastNonConfigurationInstance()
returns the data saved by onRetainNonConfigurationInstance()
. If data
is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.
If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle
that the system saves for you with the onSaveInstanceState()
callback!it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object
when your activity is restarted due to a configuration change.
To retain an object during a runtime configuration change:
onRetainNonConfigurationInstance()
method to return the object you would like to retain.getLastNonConfigurationInstance()
to recover your object.When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance()
between the onStop()
and onDestroy()
callbacks. In your implementation of onRetainNonConfigurationInstance()
, you can return any Object
that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance()
to return an object carrying your data and then retrieve the data when your activity starts again with getLastNonConfigurationInstance()
. For example:
@Override public Object onRetainNonConfigurationInstance() { final MyDataObject data = collectMyLoadedData(); return data; }
Caution: While you can return any object, you should never pass an object that is tied to the Activity
, such as a Drawable
, an Adapter
, a View
or any other object that's associated with a Context
. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)
Then retrieve the data when your activity starts again:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); if (data == null) { data = loadMyData(); } ... }
In this case, getLastNonConfigurationInstance()
returns the data saved by onRetainNonConfigurationInstance()
. If data
is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.
If restarting your activity requires that you recover large sets of data, re-establish a network connection, or perform other intensive operations, then a full restart due to a configuration change might be a slow user experience. Also, it might not be possible for you to completely restore your activity state with the Bundle
that the system saves for you with the onSaveInstanceState()
callback!it is not designed to carry large objects (such as bitmaps) and the data within it must be serialized then deserialized, which can consume a lot of memory and make the configuration change slow. In such a situation, you can alleviate the burden of reinitializing your activity by retaining a stateful Object
when your activity is restarted due to a configuration change.
To retain an object during a runtime configuration change:
onRetainNonConfigurationInstance()
method to return the object you would like to retain.getLastNonConfigurationInstance()
to recover your object.When the Android system shuts down your activity due to a configuration change, it calls onRetainNonConfigurationInstance()
between the onStop()
and onDestroy()
callbacks. In your implementation of onRetainNonConfigurationInstance()
, you can return any Object
that you need in order to efficiently restore your state after the configuration change.
A scenario in which this can be valuable is if your application loads a lot of data from the web. If the user changes the orientation of the device and the activity restarts, your application must re-fetch the data, which could be slow. What you can do instead is implement onRetainNonConfigurationInstance()
to return an object carrying your data and then retrieve the data when your activity starts again with getLastNonConfigurationInstance()
. For example:
@Override public Object onRetainNonConfigurationInstance() { final MyDataObject data = collectMyLoadedData(); return data; }
Caution: While you can return any object, you should never pass an object that is tied to the Activity
, such as a Drawable
, an Adapter
, a View
or any other object that's associated with a Context
. If you do, it will leak all the views and resources of the original activity instance. (Leaking resources means that your application maintains a hold on them and they cannot be garbage-collected, so lots of memory can be lost.)
Then retrieve the data when your activity starts again:
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance(); if (data == null) { data = loadMyData(); } ... }
In this case, getLastNonConfigurationInstance()
returns the data saved by onRetainNonConfigurationInstance()
. If data
is null (which happens when the activity starts due to any reason other than a configuration change) then this code loads the data object from the original source.
A single string that can be referenced from the application or from other resource files (such as an XML layout).
Note: A string is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). So, you can combine string resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<string>
element's
name
will be used as the resource ID.
String
.
R.string.string_name
@string/string_name
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="string_name" >text_string</string> </resources>
res/values/strings.xml
:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="hello">Hello!</string> </resources>
This layout XML applies a string to a View:
<TextView android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" />
This application code retrieves a string:
String string = getString
(R.string.hello);
You can use either getString(int)
or getText(int)
to retrieve a string. getText(int)
will retain any rich text styling applied to the string.
An array of strings that can be referenced from the application.
Note: A string array is a simple resource that is referenced using the value provided in the name
attribute (not the name of the XML file). As such, you can combine string array resources with other simple resources in the one XML file, under one <resources>
element.
res/values/filename.xml
<string-array>
element's
name
will be used as the resource ID.
String
s.
R.array.string_array_name
<?xml version="1.0" encoding="utf-8"?> <resources> <string-array name="string_array_name"> <item >text_string</item> </string-array> </resources>
res/values/strings.xml
:
<?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>
This application code retrieves a string array:
Resources res =getResources()
; String[] planets = res.getStringArray
(R.array.planets_array);
You can add styling to your strings with HTML markup. For example:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Supported HTML elements include:
<b>
for bold text.<i>
for italic text.<u>
for underline text.Sometimes you may want to create a styled text resource that is also used as a format string. Normally, this won't work because the String.format(String, Object...)
method will strip all the style information from the string. The work-around to this is to write the HTML tags with escaped entities, which are then recovered with fromHtml(String)
, after the formatting takes place. For example:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
In this formatted string, a <b>
element is added. Notice that the opening bracket is HTML-escaped, using the <
notation.
fromHtml(String)
to convert the HTML text into styled text:
Resources res = getResources()
;
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
CharSequence styledText = Html.fromHtml(text);
Because the fromHtml(String)
method will format all HTML entities, be sure to escape any possible HTML characters in the strings you use with the formatted text, using htmlEncode(String)
. For instance, if you'll be passing a string argument to String.format()
that may contain characters such as "<" or "&", then they must be escaped before formatting, so that when the formatted string is passed through fromHtml(String)
, the characters come out the way they were originally written. For example:
String escapedUsername = TextUtil.","Html","android.text.Html","class",1 ,"Formatting and Styling","Styling with HTML markup","htmlEncode
(username); Resources res =getResources()
; String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount); CharSequence styledText = Html.fromHtml(text);
You can add styling to your strings with HTML markup. For example:
<?xml version="1.0" encoding="utf-8"?> <resources> <string name="welcome">Welcome to <b>Android</b>!</string> </resources>
Supported HTML elements include:
<b>
for bold text.<i>
for italic text.<u>
for underline text.Sometimes you may want to create a styled text resource that is also used as a format string. Normally, this won't work because the String.format(String, Object...)
method will strip all the style information from the string. The work-around to this is to write the HTML tags with escaped entities, which are then recovered with fromHtml(String)
, after the formatting takes place. For example:
<resources> <string name="welcome_messages">Hello, %1$s! You have <b>%2$d new messages</b>.</string> </resources>
In this formatted string, a <b>
element is added. Notice that the opening bracket is HTML-escaped, using the <
notation.
fromHtml(String)
to convert the HTML text into styled text:
Resources res = getResources()
;
String text = String.format(res.getString(R.string.welcome_messages), username, mailCount);
CharSequence styledText = Html.fromHtml(text);
Because the fromHtml(String)
method will format all HTML entities, be sure to escape any possible HTML characters in the strings you use with the formatted text, using htmlEncode(String)
. For instance, if you'll be passing a string argument to String.format()
that may contain characters such as "<" or "&", then they must be escaped before formatting, so that when the formatted string is passed through fromHtml(String)
, the characters come out the way they were originally written. For example:
String escapedUsername = TextUtil.","TextUtils","android.text.TextUtils","class",0htmlEncode
(username); Resources res =getResources()
; String text = String.format(res.getString(R.string.welcome_messages), escapedUsername, mailCount); CharSequence styledText = Html.fromHtml(text);