Search code examples
androidandroid-layoutandroid-themeandroid-styles

Is it possible to reference attributes from styles.xml file?


I want to give the user the possibility to switch the colors skin of my entire application. I mean to switch the style of some custom views of the app dynamically when the user presses a button of the screen. I know that if you call Activity.setTheme() before onCreate() method, you can change the theme of the app dynamically, but normal Views (for example, NavigationView) with custom styles applied on their xml layout, do not have setTheme or setStyle methods, so it is does not appear possible to change their style dynamically.

I think that my objective would be possible referencing colors declared in an AppTheme declared inside styles.xml file. I mean, i can have two AppThemes declared, each one with one set of colors, and then, in the custom styles declared for the custom views, reference the colors. Something like this:

<resources>
    <style name="AppTheme" parent="Theme.AppCompat">
        <item name="customColor">#111111</item>
    </style>

    <style name="AppTheme.AnotherColor" parent="Theme.AppCompat">
        <item name="customColor">#222222</item>
    </style>

    <style name="CustomActionBar">
        <!-- title text color -->
        <item name="android:textColorPrimary">@styles/customColor</item>
    </style>
</resources>

So, by default, the custom Color declared on my "AppTheme" will be applied by default, using color 111111. But when I change the theme of my app using setTheme(R.styles.AppTheme_AnotherColor) the color applied will be 222222. If this would be possible it would be perfect! but it is not possible or I don't know how to access to a color declared inside a style directly from another style of the same styles.xml file. I mean that @styles/customColor is not correct and I don't know how to access that color.

How can this be achieved?


Solution

  • Yes, it is definitely possible to add custom attributes and colors to the themes. For this you need to:

    1. Define your custom attribute in your res/values/attrs.xml file:

      <resources>
          <attr name="customColor" format="color" />
      </resources>
      
    2. Define the attribute's value in your themes:

      <style name="AppTheme" parent="Theme.AppCompat">
          <item name="customColor">#111111</item>
      </style>
      
      <style name="AppTheme.AnotherColor" parent="Theme.AppCompat">
          <item name="customColor">#222222</item>
      </style>
      
    3. Use your custom attribute in your styles:

      <style name="CustomActionBar">
          <!-- title text color -->
          <item name="android:textColorPrimary">?attr/customColor</item>
      </style>