Working with Resources and Themes in Android
One of the key aspects of Android development is effectively managing resources such as colors, strings, and images while ensuring a consistent design with themes. In this article, we’ll explore how to handle these resources and implement both light and dark themes in an Android app.
Managing Resources: Colors, Strings, and Images
Colors in Android apps are typically stored in the res/values/colors.xml
file. Defining colors in a centralized file makes it easier to update them consistently across the app.
Example (colors.xml
):
<resources>
<color name="primaryColor">#6200EE</color>
<color name="primaryDarkColor">#3700B3</color>
<color name="accentColor">#03DAC5</color>
</resources>
To use these colors in an XML layout:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello, World!"
android:textColor="@color/primaryColor" />
Or in Kotlin:
textView.setTextColor(ContextCompat.getColor(this, R.color.primaryColor))
Strings
Hardcoding strings directly in the UI is not a good practice. Instead, we use res/values/strings.xml
to store text resources.
Example (strings.xml
):
<resources>
<string name="app_name">MyApp</string>
<string name="welcome_message">Welcome to MyApp!</string>
</resources>
Usage in XML:
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/welcome_message" />
Usage in Kotlin:
val message = getString(R.string.welcome_message)
textView.text = message
Images
Images in Android apps are stored in the res/drawable/
folder.
To use an image in XML:
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/logo" />
In Kotlin:
imageView.setImageResource(R.drawable.logo)
To support different screen resolutions, place images in folders like drawable-hdpi
, drawable-mdpi
, and drawable-xhdpi
.
Implementing Light and Dark Themes
With modern Android development, supporting both light and dark themes improves user experience and accessibility.
Defining Themes
Themes are defined in res/values/themes.xml
(for light mode) and res/values-night/themes.xml
(for dark mode).
Light Theme (themes.xml
):
<resources>
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
<item name="colorPrimary">@color/primaryColor</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorBackground">@color/white</item>
<item name="colorOnBackground">@color/black</item>
</style>
</resources>
Dark Theme (themes-night.xml
):
<resources>
<style name="Theme.MyApp" parent="Theme.MaterialComponents.DayNight">
<item name="colorPrimary">@color/primaryDarkColor</item>
<item name="colorOnPrimary">@color/white</item>
<item name="colorBackground">@color/black</item>
<item name="colorOnBackground">@color/white</item>
</style>
</resources>
Android will automatically apply the appropriate theme based on the system settings.
Switching Themes Manually
If you want to provide users with an option to switch between light and dark themes, you can use AppCompatDelegate
.
fun switchTheme(isDarkMode: Boolean) {
val mode = if (isDarkMode) {
AppCompatDelegate.MODE_NIGHT_YES
} else {
AppCompatDelegate.MODE_NIGHT_NO
}
AppCompatDelegate.setDefaultNightMode(mode)
}
You can store the user’s preference using SharedPreferences
and apply the selected theme when the app starts.
Managing resources efficiently makes your app more scalable and maintainable. Using XML to store colors, strings, and images helps in localization and theme customization. Implementing light and dark themes improves user experience, and Jetpack’s DayNight
theme simplifies the process.