Setting different resources for different themes

In some situations we might need to use different resources for different themes for the same view. This tutorial demonstrates how to set different image, string and color resources for the same view in different themes.

Let’s say, the app has an ImageView and a TextView and we want to set different images for the image view and different text and text colors when the theme is changed.

Two themes are created editing the res/values/styles.xml like the following.

<!-- Base application theme. -->
    <style name="MyLightTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimaryLT</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDarkLT</item>
        <item name="colorAccent">@color/colorAccentLT</item>
    </style>
 
    <style name="MyDarkTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimaryDT</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDarkDT</item>
        <item name="colorAccent">@color/colorAccentDT</item>
    </style>

In the above lines we have created two themes named MyLightTheme and MyDarkTheme.

Now we have to create three attributes in the styles.xml that will keep the reference tag of our resources.

    <!-- All theme dependent resources will be referenced here -->
    <attr name="thImageIcon" format="reference"></attr>
    <attr name="thColorText" format="reference"></attr>
    <attr name="thStringText" format="reference"></attr>

In the next step we shall have to add the resources as item in the respective themes by the name of those attributes.
Inside the light theme

    <!-- setting theme dependent resources here -->
    <item name="thImageIcon">@drawable/day</item>
    <item name="thColorText">@color/colorDayText</item>
    <item name="thStringText">@string/day_text</item>

and inside the dark theme.

     <!-- setting theme dependent resources here -->
     <item name="thImageIcon">@drawable/night</item>
     <item name="thColorText">@color/colorNightText</item>
     <item name="thStringText">@string/night_text</item>

Finally our styles.xml file will look like the following.

<resources>
 
    <!-- Base application theme. -->
    <style name="MyLightTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimaryLT</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDarkLT</item>
        <item name="colorAccent">@color/colorAccentLT</item>
        <!-- setting theme dependent resources here -->
        <item name="thImageIcon">@drawable/day</item>
        <item name="thColorText">@color/colorDayText</item>
        <item name="thStringText">@string/day_text</item>
    </style>
 
    <style name="MyDarkTheme" parent="Theme.AppCompat">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimaryDT</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDarkDT</item>
        <item name="colorAccent">@color/colorAccentDT</item>
        <!-- setting theme dependent resources here -->
        <item name="thImageIcon">@drawable/night</item>
        <item name="thColorText">@color/colorNightText</item>
        <item name="thStringText">@string/night_text</item>
    </style>
 
    <!-- All theme dependent resources will be referenced here -->
    <attr name="thImageIcon" format="reference"></attr>
    <attr name="thColorText" format="reference"></attr>
    <attr name="thStringText" format="reference"></attr>
 
</resources>

Now in our activity_main.xml file we have to link the attributes in the following way.
For oure image view

<ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="7"
        android:src="?attr/thImageIcon"
        android:layout_gravity="center_horizontal"
        android:padding="?dialogPreferredPadding"
        android:scaleType="centerInside"/>

In the above snippet

android:src="?attr/thImageIcon"

is linking our image view with the corresponding attribute.
Similarly we can set text view colors by adding

android:textColor="?attr/thColorText"

and text by adding

android:text="?attr/thStringText"

property in our text view.

Finally our activity_main.xml looks like the following

<?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:weightSum="10"
    tools:context="com.example.themeresource.MainActivity">
 
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="7"
        android:src="?attr/thImageIcon"
        android:layout_gravity="center_horizontal"
        android:padding="?dialogPreferredPadding"
        android:scaleType="centerInside"/>
 
    <TextView
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.5"
        android:gravity="center|top"
        android:textStyle="bold"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="?attr/thColorText"
        android:text="?attr/thStringText"
        android:id="@+id/textView" />
 
    <RadioGroup xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:orientation="horizontal"
        android:paddingLeft="?dialogPreferredPadding"
        android:layout_weight="1.5">
 
        <RadioButton
            android:id="@+id/radioButtonDay"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:text="@string/day"
            android:textStyle="bold"
            android:layout_weight="0.5"
            android:checked="true"
            android:onClick="onRadioButtonClicked" />
 
        <RadioButton
            android:id="@+id/radioButtonNight"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_gravity="top"
            android:text="@string/night"
            android:textStyle="bold"
            android:layout_weight="0.5"
            android:onClick="onRadioButtonClicked" />
    </RadioGroup>
 
</LinearLayout>

The screenshots of the simple app that was build to demonstrate the example are attached below.

light-themedark-theme

The full source code can be found here.

Leave a Comment

Your email address will not be published. Required fields are marked *