Search code examples
androidandroid-styles

Changing themes and styles based on the Android version on build


I know I can add different XMLs for different API levels, for example having different styles for values-v21 and values-v19. What I'm trying to understand is how the build system actually works with those different values? So for example if I have the bulk of my styles common across all APIs and one item of one style changes between 21 and the rest, do I:

1) Copy the whole styles.xml into v21 and change the one value I need to change

2) Only add that one style that changed to styles.xml under v21

3) Only add that one item of that one style that changed under 21

It's confusing and I couldn't find any documentation how the built process handles merging styles.


Solution

  • Rules are quite clear:

    1. While running Android selects the best-matching style
    2. If selected style is a child style, Android merges its items with parent best-matching style

      If you provide your mutable item via a reference, just define its value to match selected api version.

      <style name="SomeStyle">
          <item name="someColor">@color/some_color</item>
      </style>
      

    You can have some_color.xml in color-v21 folder for API 21 and a common version of this file in a color folder for all other api levels.

    Example:

    You want to have the following style for non-v21 API

        <style name="FinalStyle">
            <item name="commonText">It\'s a common text</item>
            <item name="specificDrawable">@drawable/icon</item>
            <item name="specificColor">@color/primary_color</item>
            <item name="specificText">non-v21</item>
        </style>
    

    And the following style for v21 API

        <style name="FinalStyle">
            <item name="commonText">It\'s a common text</item>
            <item name="specificDrawable">@drawable/icon</item>
            <item name="specificColor">@color/secondary_color</item>
            <item name="specificText">v21</item>
        </style>
    

    Specific-parameters differ between v21/non-v21 API, common parameters are common.

    How to do it?

    • res/values/styles.xml

      <style name="BaseStyle">
          <item name="commonText">It\'s a common text</item>
          <item name="specificDrawable">@drawable/icon</item>
      </style>
      
      <style name="FinalStyle" parent="BaseStyle">
          <item name="specificColor">@color/primary_color</item>
          <item name="specificText">non-v21</item>
      </style>
      
    • res/values-v21/styles.xml

      <style name="FinalStyle" parent="BaseStyle">
          <item name="specificColor">@color/secondary_color</item>
          <item name="specificText">v21</item>
      </style>
      
    • res/drawable/icon.png Common icon

    • res/drawable-v21/icon.png v21 icon

    When Android searches FinalStyle for v21, it selects FinalStyle definition from res/values-v21 as best-matching style, and merges with BaseStyle. In this example there is also another best-matching resource search, when Android searches @drawable/icon.