Modify existing theme - android

I would like to know if it is possible (and how) to customize an existing theme.
What I'm looking for is how can I retrieve a certain attribute (i.e. color) and change it when the Activity starts and reapply the modified theme before setContentView().
Similar to setTheme(), but instead of using a resource id, use the modified theme.

Why not just make your own theme, setting the android:parent to the theme you want to copy, then set your own attributes? That is demonstrated in this documentation, like so:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CodeFont" parent="#android:style/TextAppearance.Medium">
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:textColor">#00FF00</item>
<item name="android:typeface">monospace</item>
</style>
</resources>
In this case, the CodeFont style will be identical to the TextAppearance.Medium style, except for the items specified here. You can do the same with any theme, including the default Holo or Dark theme or whatnot.

Based on further research and Eric's comment there is not yet a possible way to modify a theme programmatically. Different themes can be applied programmatically but not modified. Once the style is set in XML, it cannot be modified.

Related

Overriding the theme attribute inside of a style?

I have a project where I defined all the styles in the theme (Button style, Checkbox Style, EditText style and so on) This way I don't need to apply any style or theme in the layouts where I use those views, because they are applied automatically by my AppTheme.
Now I encountered a problem. I wanted to define the Switch style inside the theme but it should use another color for the colorControlActivated and colorControlHighlight. By default it uses the colorPrimary which I defined in the theme, but what if I want to change that.
The problem can be fixed easy with a theme overlay or a style where I override the needed attributes that I mentioned above and apply that style/theme everywhere where I use the Swtch view. But I want to know if I can avoid that and define a default style for my Switch views inside the same theme where the colorControlActivated and colorControlHighlight are already defined.
I tried several things but this looked like the one that actually might work but it does not:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorControlActivated">#color/colorPrimary</item>
<item name="colorControlHighlight">#color/colorPrimary</item>
<item name="colorSwitchThumbNormal">#color/white</item>
<item name="switchStyle">#style/SwitchStyle</item>
</style>
<style name="AppTheme.GreenControlOverlay">
<item name="colorControlActivated">#color/green</item>
<item name="colorControlHighlight">#color/green</item>
</style>
the SwitchStyle looks like this
<style name="SwitchStyle" parent="Widget.AppCompat.CompoundButton.Switch">
<item name="android:theme">#style/AppTheme.GreenControlOverlay</item>
</style>
I dont know why this is not working because if I set the android:theme inside my AppTheme directly it does override the colorControl attributes, but if you override it from a style it does not work. If I apply this GreenControlOverlay on the Switch view inside of my layout it also works.
Is it even possible to do this?
If you have any questions please don't hesitate to ask. I hope I explained my problem well.

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?
Yes, it is definitely possible to add custom attributes and colors to the themes. For this you need to:
Define your custom attribute in your res/values/attrs.xml file:
<resources>
<attr name="customColor" format="color" />
</resources>
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>
Use your custom attribute in your styles:
<style name="CustomActionBar">
<!-- title text color -->
<item name="android:textColorPrimary">?attr/customColor</item>
</style>

text appearance doesn't work inside my theme

I'm trying to put a style in all my app, so i created a theme with my style inside :
<resources>
<style name="MyTheme" parent="android:Theme.Holo.Light">
<item name="android:textAppearance">#style/subtitle</item>
</style>
<style name="subtitle parent="#android:style/TextAppearance">
<item name="android:textColor">#color/purple</item>
<item name="android:textSize">40sp</item>
</style>
</resources>
But textAppearance doesn't work it stay the same, but when i put something like textColor in my theme, it works
This is a quite old question, but the answer may help someone.
The key to solve this is in the "precedence order of styling techniques" here: 
on the top is the highest precedence, at the bottom is the lowest precedence.
As we can see theme has the lowest precedence, in your example, your android:textAppearance property is being overridden by the default style of every view that accepts this attribute, the default style property is defined in every them for every specific view that accepts this attribute, in this case android:Theme.Holo.Light provides the default style for textView as android:textViewStyle... for buttons is android:buttonStyle (which inherits its textAppearance from TextView), and so on.
So if you are trying to apply that android:textAppearance property to a TextVew you should use <item name="android:textViewStyle">#style/subtitle</item> instead of <item name="android:textAppearance">#style/subtitle</item> inside MyTheme. Away to veryfy this is setting android:textViewStyle to null, that way your current code will work fine with textViews <item name="android:textViewStyle">null</item>
This post explains this precedence a bit deeper:
https://medium.com/androiddevelopers/whats-your-text-s-appearance-f3a1729192d
What I can see is, you have not declared the color in your xml for theme. Please add the following line within the <resources> and try. Your xml will look like:
<resources>
<style name="MyTheme" parent="android:Theme.Holo.Light">
<item name="android:textAppearance">#style/subtitle</item>
</style>
<color name="purple">code for your color</color>
<style name="subtitle parent="#android:style/TextAppearance">
<item name="android:textColor">#color/purple</item>
<item name="android:textSize">40sp</item>
</style>
I think this will do.
Depends on your target API you need to put your customization code in different /res/values-vxx/style.xml files.
For TextView, try android:textAppearanceSmall inside your theme instead.

android: How can I define custom colors, drawables, etc. in themes?

I hope I can explain what I'm after. In essence, my users have asked me to allow different looks in my application, which I hope I can do with themes.
I hoped I could do something like this:
<style name="NewTheme" parent="android:Theme.Dark">
<item name="labelColor">#f90</item>
<item name="buttonColor">#fff</item>
<item name="buttonBg">#drawable/button</item>
</style>
<style name="OldTheme" parent="android:Theme.Dark">
<item name="labelColor">#fa0</item>
<item name="buttonColor">#88f</item>
<item name="buttonBg">#drawable/button_old</item>
</style>
And then reference these values in my styles.xml:
<style name="labelStyle">
<item name="android:textColor>#labelColor</item>
</style>
<style name="buttonStyle">
<item name="android:textcolor">#buttonColor</item>
<item name="android:background">#buttonBg</item>
</style>
I know this syntax is wrong, but what might be the right syntax? Basically, I want to create sets of attributes (color, background, a couple other things) and select them based on theme.
To work with themes and styles in Android you have to:
Define one or more themes in themes.xml and set the definitions of
your styles there.
Define custom attributes, a.k.a. custom styles, in attrs.xml.
Describe what the values of your custom styles are in styles.xml.
In your layout files, give your views a style attribute, which has a
custom style name as their values.
Set the theme of your application or activity in either
AndroidManifest.xml or in the Activity's onCreate(). This is done by calling setTheme() in the activity's onCreate() method, before any call to setContentView().
To change the theme, you simply need to restart your activity.
Iadvice you to look at this tutorial it deals with all that a programmer want to work on android themes (text color, text formatting, state list drawable etc ...)

Styles and themes in Android

I'm trying to learn something about styles and themes for Android. I've found that, if I add the android:theme attribute in the manifest for Application or Activity, style is applied to the entire app/activity. I think it would be useful to be able to define a style that is applied for example only to buttons. Do you know if there is a way to apply a certain style only for a certain kind on Views, as in CSS?
Here's a general example:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="CustomButton" parent="#android:style/Widget.Button">
<item name="android:textColor">#FF0000</item>
</style>
<style name="CustomTheme" parent="android:Theme">
<item name="android:buttonStyle>#style/CustomButton</item>
</style>
</resources>
It's easy to do, just read the official reference:
http://developer.android.com/guide/topics/ui/themes.html
EDIT
Obviously you'll need to specify the style you create on each button/view you want it to be applied (like in css, for the class attribute)

Categories

Resources