Android Styles and Themes: Organizing Files for Kotlin XML Development

When developing Android applications using Kotlin and XML, maintaining a well-organized structure for styles and themes is crucial for code maintainability, reusability, and consistency. Properly structuring these files can significantly impact the scalability and ease of managing the app’s UI. This blog post delves into the best practices for organizing styles and themes files in your Android projects.

Why Proper Organization Matters

Consistent and well-structured styles and themes enable:

  • Maintainability: Easy updates and modifications to your app’s appearance.
  • Reusability: Sharing styles and themes across multiple activities or fragments.
  • Consistency: Uniform look and feel throughout the application.
  • Readability: Quick understanding of styling attributes, aiding in debugging and collaboration.

File Naming Conventions

Establishing clear and descriptive naming conventions is fundamental.

styles.xml

The styles.xml file should contain general and reusable styles.

themes.xml

The themes.xml file is dedicated to theme definitions applied to the entire application or specific activities.

It is also recommended to create specific files when your project grows:

  • styles_buttons.xml: Contains styles specific to buttons.
  • styles_textviews.xml: Contains styles specific to text views.
  • themes_dark.xml: For dark mode themes.
  • themes_light.xml: For light mode themes.

Directory Structure

Keep all XML files related to styles and themes within the res/values directory. As the project grows, it might be useful to categorize files based on features or modules.


res/
    values/
        styles.xml
        themes.xml
        styles_buttons.xml
        styles_textviews.xml
        themes_dark.xml
        themes_light.xml

Structuring Styles and Themes

Break down styles and themes into logical, modular components.

Base Styles

Define base styles that encapsulate common attributes. These act as parent styles for more specific styles.


<style name="BaseTextView">
    <item name="android:textColor">@color/default_text_color</item>
    <item name="android:textSize">16sp</item>
</style>

Specific Styles

Create styles that inherit from base styles to add specific modifications.


<style name="TitleTextView" parent="BaseTextView">
    <item name="android:textSize">20sp</item>
    <item name="android:textStyle">bold</item>
</style>

Themes

Define themes to group styles that apply to the entire application or specific activities. A theme is a collection of styles applied to different parts of your application.


<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
    <item name="android:textColorPrimary">@color/primaryTextColor</item>
</style>

Dark Mode Themes

Separate dark mode themes to ensure proper handling of night mode.


<style name="AppTheme.Dark" parent="Theme.MaterialComponents.NoActionBar">
    <item name="colorPrimary">@color/dark_colorPrimary</item>
    <item name="colorPrimaryDark">@color/dark_colorPrimaryDark</item>
    <item name="colorAccent">@color/dark_colorAccent</item>
    <item name="android:textColorPrimary">@color/dark_primaryTextColor</item>
    <item name="android:windowBackground">@color/dark_background</item>
</style>

Applying Styles and Themes

Applying Styles to Views

Apply styles to individual views in your layout files.


<TextView
    android:id="@+id/titleTextView"
    style="@style/TitleTextView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Title" />

Applying Themes to Activities

Apply themes to the entire activity or application in the AndroidManifest.xml file.


<application
    android:theme="@style/AppTheme">
    <activity
        android:name=".MainActivity"
        android:theme="@style/AppTheme">
        <intent-filter>
            <action android:name="android:intent.action.MAIN" />
            <category android:name="android:intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>

Best Practices

Use Descriptive Names

Ensure that style and theme names are self-explanatory.


<style name="Button.Primary"></style>  <!-- Good -->
<style name="Btn1"></style>         <!-- Avoid -->

Minimize Redundancy

Leverage inheritance to avoid repeating attributes.

Use Theme Attributes

Use theme attributes (?attr/) to reference values defined in the current theme.


<item name="android:textColor">?attr/textColorPrimary</item>

Separate Concerns

Keep style and theme definitions specific to their roles.

Consistent Formatting

Maintain uniform XML formatting for readability.

Example: Practical Implementation

Step 1: Define Base Styles


<!-- res/values/styles.xml -->
<style name="BaseButton">
    <item name="android:layout_width">wrap_content</item>
    <item name="android:layout_height">wrap_content</item>
    <item name="android:textAllCaps">false</item>
    <item name="android:padding">12dp</item>
</style>

Step 2: Define Specific Button Styles


<!-- res/values/styles_buttons.xml -->
<style name="Button.Primary" parent="BaseButton">
    <item name="android:backgroundTint">@color/colorPrimary</item>
    <item name="android:textColor">@color/white</item>
</style>

<style name="Button.Secondary" parent="BaseButton">
    <item name="android:backgroundTint">@color/colorSecondary</item>
    <item name="android:textColor">@color/white</item>
</style>

Step 3: Define Themes


<!-- res/values/themes.xml -->
<style name="AppTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
    <item name="colorPrimary">@color/colorPrimary</item>
    <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
    <item name="colorAccent">@color/colorAccent</item>
</style>

Step 4: Apply the Style in Layout XML


<Button
    android:id="@+id/primaryButton"
    style="@style/Button.Primary"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Primary Button" />

<Button
    android:id="@+id/secondaryButton"
    style="@style/Button.Secondary"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Secondary Button" />

Conclusion

Properly organizing styles and themes in Kotlin XML development is vital for maintaining a clean, consistent, and scalable Android application. Following best practices for file naming, directory structure, and modular component design enables teams to manage UI appearance efficiently, improve code reusability, and enhance overall project maintainability. By adhering to these guidelines, developers can create visually appealing and cohesive Android applications with less effort and increased reliability.