Android Themes: Defining & Applying to Activities (Kotlin XML)

In Android development, themes play a crucial role in defining the look and feel of your application. They provide a way to maintain a consistent design across your app by centralizing style attributes such as colors, fonts, and sizes. Applying themes correctly through the AndroidManifest.xml file is essential for a uniform user experience. This comprehensive guide covers how to define and apply themes to your activities and application using Kotlin XML development for Android.

Understanding Themes in Android

Themes are a set of attributes that define the visual style of your Android application. These attributes include:

  • Color: Primary color, accent color, background color, text color, etc.
  • Typography: Font family, font size, text styles, etc.
  • Styles: Specific styles for UI components like buttons, text fields, and dialogs.

By defining and applying themes, you ensure that your application has a consistent look and feel, making it more professional and user-friendly.

Step 1: Defining Themes in styles.xml

The first step is to define your themes in the res/values/styles.xml file. This file is where you define the style attributes that make up your theme.

Example: Defining a Custom Theme

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
        <item name="android:windowBackground">@color/windowBackground</item>
        <item name="android:navigationBarColor">@color/navigationBarColor</item>
    </style>

    <!-- Define colors -->
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="textColorPrimary">#212121</color>
    <color name="windowBackground">#FFFFFF</color>
    <color name="navigationBarColor">#000000</color>

</resources>

In this example, we’ve defined a custom theme called AppTheme which inherits from Theme.MaterialComponents.Light.NoActionBar. We’ve also customized various attributes such as colorPrimary, colorAccent, textColorPrimary, and windowBackground to match our desired look.

Step 2: Applying Themes to Activities in AndroidManifest.xml

To apply the defined theme to specific activities, you need to modify the AndroidManifest.xml file. You can set a theme for the entire application or for individual activities.

Applying Theme to the Entire Application

To apply a theme to the entire application, add the android:theme attribute to the <application> tag in your AndroidManifest.xml file.

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Here, we set the theme for the entire application to @style/AppTheme. This means that every activity in the application will inherit this theme unless explicitly overridden.

Applying Theme to Individual Activities

To apply a different theme to a specific activity, add the android:theme attribute to the <activity> tag for that activity in the AndroidManifest.xml file.

<application
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".SecondActivity"
        android:theme="@style/SecondActivityTheme">
    </activity>
</application>

In this example, MainActivity uses the default application theme @style/AppTheme, while SecondActivity uses a different theme called @style/SecondActivityTheme.

Example: Defining a Theme for SecondActivity

First, define the SecondActivityTheme in styles.xml:

<resources>
    <!-- Second Activity Theme -->
    <style name="SecondActivityTheme" parent="Theme.MaterialComponents.Light.DarkActionBar">
        <item name="colorPrimary">@color/secondPrimaryColor</item>
        <item name="colorPrimaryDark">@color/secondPrimaryDarkColor</item>
        <item name="colorAccent">@color/secondAccentColor</item>
        <item name="android:textColorPrimary">@color/secondTextColorPrimary</item>
        <item name="android:windowBackground">@color/secondWindowBackground</item>
        <item name="android:navigationBarColor">@color/secondNavigationBarColor</item>
    </style>

    <!-- Define colors for the second theme -->
    <color name="secondPrimaryColor">#E91E63</color>
    <color name="secondPrimaryDarkColor">#C2185B</color>
    <color name="secondAccentColor">#FFC107</color>
    <color name="secondTextColorPrimary">#FFFFFF</color>
    <color name="secondWindowBackground">#FCE4EC</color>
    <color name="secondNavigationBarColor">#000000</color>
</resources>

Step 3: Theme Inheritance and Overriding

Android supports theme inheritance, allowing you to create base themes and extend them for specific activities or components. You can also override specific attributes to customize the theme further.

Theme Inheritance

When creating a new theme, you can inherit from an existing theme using the parent attribute. This allows you to reuse common style attributes and only override the ones you want to change.

Overriding Attributes

Within a theme, you can override specific attributes to customize the look and feel. For example, you can override the colorPrimary for a specific activity to give it a different color scheme.

Example: Overriding Attributes in styles.xml

<resources>
    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
        <!-- Customize your theme here. -->
        <item name="colorPrimary">@color/colorPrimary</item>
        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
        <item name="colorAccent">@color/colorAccent</item>
        <item name="android:textColorPrimary">@color/textColorPrimary</item>
        <item name="android:windowBackground">@color/windowBackground</item>
        <item name="android:navigationBarColor">@color/navigationBarColor</item>
    </style>

    <!-- Theme for MainActivity overriding colorPrimary -->
    <style name="MainActivityTheme" parent="AppTheme">
        <item name="colorPrimary">@color/mainActivityPrimaryColor</item>
    </style>

    <!-- Define colors -->
    <color name="colorPrimary">#3F51B5</color>
    <color name="colorPrimaryDark">#303F9F</color>
    <color name="colorAccent">#FF4081</color>
    <color name="textColorPrimary">#212121</color>
    <color name="windowBackground">#FFFFFF</color>
    <color name="navigationBarColor">#000000</color>

    <color name="mainActivityPrimaryColor">#4CAF50</color>
</resources>

Here, MainActivityTheme inherits from AppTheme but overrides the colorPrimary attribute with a new color, @color/mainActivityPrimaryColor.

Best Practices for Defining and Applying Themes

  • Use Semantic Naming: Use clear and descriptive names for your themes and style attributes to make your code more readable.
  • Consistent Design: Maintain a consistent design across your application by using a base theme and extending it for specific activities or components.
  • Theme Variations: Create different theme variations for different contexts, such as light and dark themes, to improve the user experience.
  • Leverage Styles: Use styles for individual UI components to avoid repetitive styling in your layouts.
  • Test on Multiple Devices: Ensure that your themes look good on a variety of devices and screen sizes by testing your application thoroughly.

Troubleshooting Common Issues

  • Theme Not Applying:
    • Ensure that the theme is correctly defined in styles.xml.
    • Verify that the android:theme attribute is correctly set in AndroidManifest.xml for the activity or application.
    • Clean and rebuild your project to resolve any caching issues.
  • Inconsistent Styling:
    • Check for any conflicting styles or attributes that may be overriding the theme settings.
    • Ensure that you are using a base theme and extending it for consistent styling.

Conclusion

Defining and applying themes correctly is a fundamental aspect of Android development. By centralizing style attributes and applying them through the AndroidManifest.xml file, you can ensure that your application has a consistent and professional look and feel. This guide has covered the steps to define themes in styles.xml, apply them to activities and applications, and use theme inheritance and overriding to customize your application’s appearance. By following the best practices outlined in this guide, you can create visually appealing and user-friendly Android applications.