First of all, this question asks a very similar question. However, my question has a subtle difference.
What I'd like to know is whether it is possible to programmatically change the colorPrimary
attribute of a theme to an arbitrary color?
So for example, we have:
<style name="AppTheme" parent="android:Theme.Material.Light">
<item name="android:colorPrimary">#ff0000</item>
<item name="android:colorAccent">#ff0000</item>
</style>
At runtime, the user decides he wants to use #ccffff
as a primary color. Ofcourse there's no way I can create themes for all possible colors.
I don't mind if I have to do hacky stuff, like relying on Android's private internals, as long as it works using the public SDK.
My goal is to eventually have the ActionBar
and all widgets like a CheckBox
to use this primary color.
I read the comments about contacts app and how it use a theme for each contact.
Probably, contacts app has some predefine themes (for each material primary color from here: http://www.google.com/design/spec/style/color.html).
You can apply a theme before a the setContentView method inside onCreate method.
Then the contacts app can apply a theme randomly to each user.
This method is:
But this method has a problem, for example it can change the toolbar color, the scroll effect color, the ripple color, etc, but it cant change the status bar color and the navigation bar color (if you want to change it too).
Then for solve this problem, you can use the method before and:
This two method change the navigation and status bar color. Remember, if you set your navigation bar translucent, you can't change its color.
This should be the final code:
You can use a switch and generate random number to use random themes, or, like in contacts app, each contact probably has a predefine number associated.
A sample of theme:
Sorry for my english.
You cannot change the color of colorPrimary, but you can change the theme of your application by adding a new style with a different colorPrimary color
and inside the activity set theme
The GreenMatter library can help you achieve the functionality you are looking for:
https://github.com/negusoft/GreenMatter
You can use Theme.applyStyle to modify your theme at runtime by applying another style to it.
Let's say you have these style definitions:
Now you can patch your theme at runtime like so:
The method
applyStyle
has to be called before the layout gets inflated! So unless you load the view manually you should apply styles to the theme before callingsetContentView
in your activity.Of course this cannot be used to specify an arbitrary color, i.e. one out of 16 million (2563) colors. But if you write a small program that generates the style definitions and the Java code for you then something like one out of 512 (83) should be possible.
What makes this interesting is that you can use different style overlays for different aspects of your theme. Just add a few overlay definitions for
colorAccent
for example. Now you can combine different values for primary color and accent color almost arbitrarily.You should make sure that your overlay theme definitions don't accidentally inherit a bunch of style definitions from a parent style definition. For example a style called
AppTheme.OverlayRed
implicitly inherits all styles defined inAppTheme
and all these definitions will also be applied when you patch the master theme. So either avoid dots in the overlay theme names or use something likeOverlay.Red
and defineOverlay
as an empty style.I used the Dahnark's code but I also need to change the ToolBar background:
Themes are immutable, you can't.