3

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?

Poger
  • 1,897
  • 18
  • 16
NullPointerException
  • 36,107
  • 79
  • 222
  • 382
  • Custom attributes are referenced using `?attr/customAttributeName`, so in your case you need to put `?attr/customColor` in your `CustomActionBar` theme. – TR4Android Aug 15 '16 at 17:51
  • @TR4Android does not find the atribute. Test it please. You should reference it from another – NullPointerException Aug 15 '16 at 18:00
  • Have you defined it in your `attrs.xml` file? Each custom attribute needs to be defined there so it can be found. Put something like `` in that file. – TR4Android Aug 15 '16 at 18:05
  • @TR4Android And will I have the possibility to change it's value in my AppTheme and AppTheme.AnotherColor dinamically? – NullPointerException Aug 15 '16 at 18:06
  • Yes, I've made it work in one of my apps. Themes and styles on Android can be at perky at times though... – TR4Android Aug 15 '16 at 18:07
  • @TR4Android please, how to give value to that customColor inside AppTheme style? – NullPointerException Aug 15 '16 at 18:09
  • That code is just fine, use the `customColor` there without any modification. – TR4Android Aug 15 '16 at 18:09
  • @TR4Android I'm not understanding you. How to give value to the customColor inside the AppTheme Style? I can't do it. I tryed with #111111 but can't find ?attr – NullPointerException Aug 15 '16 at 18:11
  • No, you've already correctly defined your customColor, but not correctly referenced it in your `CustomActionBar` style. That's where you need to put this: `?attr/customColor` – TR4Android Aug 15 '16 at 18:14
  • @TR4Android No, you don't understand me. My english is bad. I need to set the value for customColor in my AppTheme style! After that, i will reference it in the other styles. But first i need to set it's value depending on which theme is set in my app. Do you understand me? – NullPointerException Aug 15 '16 at 18:16
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/120987/discussion-between-nullpointerexception-and-tr4android). – NullPointerException Aug 15 '16 at 18:16
  • Yes, I do. The value is defined as you've put it in your example code above, no changes need to be made there. – TR4Android Aug 15 '16 at 18:17
  • @TR4Android please accept my chat invitation two messages ago. – NullPointerException Aug 15 '16 at 18:18

1 Answers1

8

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>
    
TR4Android
  • 3,200
  • 16
  • 21
  • thank you so much. Is it possible to write the value of the custom xml attribute (created in attrs.xml) with java code? – NullPointerException Aug 15 '16 at 21:06
  • Not easily. Android themes and styles are really one of the most inflexible things. You can find a few hints [here](http://stackoverflow.com/a/34178187/5731450). – TR4Android Aug 15 '16 at 22:03
  • TR4Android it is possible to use this with a widget color¿? Widget does not have theme, so can't set the value of the attr setting the theme on the widget... must be other way – NullPointerException Aug 16 '16 at 21:13
  • Unfortunately, I have no experience with widgets, but you could try just using something like `android:background="?attr/customColor"`. – TR4Android Aug 16 '16 at 21:24