Android - Resources
Android Resources: Organizing & Accessing
Section titled “Android Resources: Organizing & Accessing”Building a robust Android application involves more than just writing Kotlin or Java code. You also need to manage various static resources that your code uses, such as images, colors, layout definitions, user interface strings, animations, fonts, and more. These resources are maintained in separate sub-directories within the res/ directory of your project.
This tutorial will guide you through organizing your application resources, specifying alternative resources for different device configurations, and accessing them efficiently in your modern Android applications.
Organize Resources in Android Studio
Section titled “Organize Resources in Android Studio”A typical Android project structure in Android Studio organizes resources as follows:
MyProject/ app/ src/ main/ AndroidManifest.xml java/ com/example/myproject/ MyActivity.java res/ animator/ (XML files for property animations, e.g., objectAnimator) anim/ (XML files for tween animations - less common now) color/ (XML files defining state list colors) drawable/ (Bitmap files: .png, .jpg, .gif; XML for shapes, vector drawables, state lists) font/ (Font files: .ttf, .otf, or XML for font families) layout/ (XML files defining UI layouts) menu/ (XML files for options menus, context menus) mipmap/ (Density-specific launcher icons: icon.png) navigation/ (XML files for Jetpack Navigation graphs) raw/ (Arbitrary files to save in their raw form) values/ (XML files for simple values: strings.xml, colors.xml, dimens.xml, styles.xml, themes.xml) xml/ (Arbitrary XML configuration files)Here’s a breakdown of common resource directories and their types:
| No. | Directory & Resource Type |
|---|---|
| 1 | animator/ XML files that define property animations (e.g., using <objectAnimator>, <valueAnimator>). Saved in res/animator/ and accessed via R.animator. |
| 2 | anim/ XML files that define older tween animations. Saved in res/anim/ and accessed via R.anim. Property animations in animator/ are generally preferred for flexibility. |
| 3 | color/ XML files that define state list of colors (e.g., for button states) or simple color resources. Saved in res/color/ and accessed via R.color. |
| 4 | drawable/ Image files (e.g., .png, .jpg, .webp) or XML files compiled into drawable resources (e.g., shapes, vector drawables, state list drawables, gradients). Saved in res/drawable/ and accessed via R.drawable. Vector drawables are highly recommended for resolution-independent graphics. |
| 5 | font/ Font files (e.g., .ttf, .otf) or XML files defining font families. Saved in res/font/ and accessed via R.font. |
| 6 | layout/ XML files that define the structure of a user interface (e.g., for an Activity or Fragment). Saved in res/layout/ and accessed via R.layout. |
| 7 | menu/ XML files that define application menus (e.g., Options Menu, Context Menu). Saved in res/menu/ and accessed via R.menu. |
| 8 | mipmap/ Primarily used for density-specific app launcher icons. Android system uses these to pick the best resolution icon for the device’s screen. Accessed via R.mipmap. |
| 9 | navigation/ XML files that define navigation graphs for apps using the Jetpack Navigation component. Saved in res/navigation/ and accessed via R.navigation. |
| 10 | raw/ Arbitrary files to save in their raw form (e.g., audio, video files). Access using Resources.openRawResource() with R.raw.filename. |
| 11 | values/ XML files containing simple values like strings, dimensions, colors, styles, and themes. Common file names include: - strings.xml: String values (R.string).- colors.xml: Color definitions (R.color).- dimens.xml: Dimension values (R.dimen).- styles.xml: UI styles (R.style).- themes.xml: Application or Activity themes (often in res/values/themes/ and res/values-night/themes/ for Material Design 3). - arrays.xml: Resource arrays (R.array).- attrs.xml: Custom attributes for custom views. |
| 12 | xml/ Arbitrary XML files that can be read at runtime using Resources.getXml(). Useful for configuration data. |
Alternative Resources
Section titled “Alternative Resources”Modern Android apps must adapt to a wide variety of devices. You should provide alternative resources to support specific device configurations, such as different screen sizes, densities, orientations, languages, and UI modes (like dark theme).
To specify configuration-specific alternatives:
- Create a new directory in
res/named<resources_name>-<config_qualifier>. For example,layout-sw600dpfor layouts on screens with a smallest width of 600dp, orvalues-esfor Spanish strings. <resources_name>is a standard resource type (e.g.,drawable,layout,values).<config_qualifier>specifies the configuration (e.g.,landfor landscape,hdpifor high density,nightfor night mode). You can combine multiple qualifiers (e.g.,drawable-en-land-hdpi).- Save the alternative resource files in this new directory. These files must have the exact same name as the default resource files. Android automatically loads the appropriate resource at runtime based on the current device configuration.
Example: Providing different drawables for various screen densities and a vector drawable as a default (or for all densities if it suits the design):
MyProject/ app/src/main/ res/ drawable/ (Default, often for vector drawables or -nodpi resources) icon.xml (Vector drawable) background.png drawable-mdpi/ (Medium density ~160dpi) background.png drawable-hdpi/ (High density ~240dpi) background.png drawable-xhdpi/ (Extra-high density ~320dpi) background.png drawable-xxhdpi/ (Extra-extra-high density ~480dpi) background.png drawable-xxxhdpi/ (Extra-extra-extra-high density ~640dpi) background.png mipmap-anydpi-v26/ (For adaptive icons) ic_launcher.xml mipmap-hdpi/ ic_launcher.png (Legacy launcher icon) ...Tip: For most icons and simple graphics, use Vector Drawables (.xml files in drawable/). They scale without quality loss and reduce APK size. For launcher icons, use Adaptive Icons and provide legacy versions in mipmap directories.
Example: Providing different layouts for portrait and landscape, and different strings for English (default) and Arabic:
MyProject/ app/src/main/ res/ layout/ (Default layout - typically portrait) activity_main.xml layout-land/ (Layout for landscape orientation) activity_main.xml values/ (Default strings - typically English) strings.xml values-ar/ (Strings for Arabic language) strings.xml (Supports Right-to-Left layouts automatically if `android:supportsRtl="true"` in Manifest)Commonly used qualifiers include: language and region (-en, -fr-rCA), smallest width (-sw<N>dp), available width/height (-w<N>dp, -h<N>dp), screen orientation (-land, -port), UI mode (-night, -car), API level (-v21). Refer to the official Android documentation for a complete list of qualifiers and best practices for providing alternative resources.
Accessing Resources
Section titled “Accessing Resources”You’ll need to access your defined resources in your Kotlin/Java code or in your XML files.
Accessing Resources in Code
Section titled “Accessing Resources in Code”When your Android application is compiled, an R class is generated. This class contains static integer IDs for all resources in your res/ directory. You use these IDs to access resources.
Example: Setting an image on an ImageView and text on a TextView in an Activity (using View Binding, the recommended way to interact with views):
First, enable View Binding in your module-level build.gradle.kts (or build.gradle) file:
// build.gradle.kts (Groovy: buildFeatures { viewBinding true })android { // ... buildFeatures { viewBinding = true }}Then, in your Activity (e.g., MyActivity.java):
package com.example.myproject;
import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;// Assuming your layout file is activity_my.xml, this class is generatedimport com.example.myproject.databinding.ActivityMyBinding;
public class MyActivity extends AppCompatActivity {
private ActivityMyBinding binding; // ViewBinding object
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Inflate the layout and get the binding object binding = ActivityMyBinding.inflate(getLayoutInflater()); setContentView(binding.getRoot());
// Access views using the binding object (e.g., if you have an ImageView with id 'myImageView') // binding.myImageView.setImageResource(R.drawable.my_image_name);
// Example from original context: Assume an ImageView with id 'myImageViewInXml' binding.myImageViewInXml.setImageResource(R.drawable.myimage); // R.drawable.myimage refers to res/drawable/myimage.png (or .xml)
// Assume a TextView with id 'messageTextViewInXml' binding.messageTextViewInXml.setText(R.string.hello_message); // R.string.hello_message refers to a string in strings.xml
// To get a color resource (e.g., from res/values/colors.xml): // int myColor = ContextCompat.getColor(this, R.color.my_custom_color); // binding.messageTextViewInXml.setTextColor(myColor); }}In this example, R.drawable.myimage refers to an image file (e.g., myimage.png or myimage.xml) located in a res/drawable* directory. R.string.hello_message refers to a string resource named hello_message defined in res/values/strings.xml.
Example: res/values/strings.xml containing hello_message:
<?xml version="1.0" encoding="utf-8"?><resources> <string name="app_name">My Application</string> <string name="hello_message">Hello from Resources!</string></resources>Example: Loading a layout in an Activity’s onCreate() method:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // This loads the layout defined in res/layout/activity_main.xml setContentView(R.layout.activity_main); }}Accessing Resources in XML
Section titled “Accessing Resources in XML”You can also reference resources directly within your XML files (e.g., layouts, styles, drawables) using the @ symbol.
Syntax: @<package_name>:<resource_type>/<resource_name>
<package_name>is optional if the resource is from your own app (usually omitted).<resource_type>is theRsubclass (e.g.,string,drawable,color,dimen).<resource_name>is the name of the resource file (without extension) or thenameattribute value in an XML resource file.
Example: res/values/colors.xml and res/values/strings.xml:
<?xml version="1.0" encoding="utf-8"?><resources> <color name="app_primary_color">#FF6200EE</color> <color name="text_error_red">#B00020</color></resources>
<!-- res/values/strings.xml --><?xml version="1.0" encoding="utf-8"?><resources> <string name="greeting">Hello World!</string> <string name="submit_button_text">Submit</string></resources>Example: Using these resources in a layout file (e.g., res/layout/activity_main.xml):
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="@dimen/activity_padding"> <!-- Assuming @dimen/activity_padding is in dimens.xml -->
<TextView android:id="@+id/greetingTextView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/greeting" android:textColor="@color/app_primary_color" android:textSize="@dimen/text_size_large" /> <!-- Assuming @dimen/text_size_large in dimens.xml -->
<Button android:id="@+id/submitButton" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/submit_button_text" android:backgroundTint="@color/app_primary_color" />
</LinearLayout>Note the use of ?attr/ for theme attributes (e.g., android:textColor="?attr/colorPrimary") which is a powerful way to create themeable UIs. This is preferred over hardcoding colors directly when the color should adapt to the app’s theme.
Understanding how to organize and access resources is fundamental to Android development, enabling you to create flexible, maintainable, and adaptable applications.