How to define attr value for Theme dynamically - android

Let me clarify the question.
I have theme like this
<style name="DefaultTheme" parent="android:Theme.Holo.Light">
<item name="android:textViewStyle">#style/DefaultTextViewStyle</item>
</style>
where
<style name="DefaultTextViewStyle" parent="android:Widget.TextView">
<item name="android:textColor">?attrTextColor</item>
</style>
for application I use the DefaultTheme theme, and I want to change value of the attrTextColor dynamically from code (to change text color for all TextView). Can I do it? How Can I do it?

For simple explication, you can do it with theme.
You have to define your attributes
<attr name="color_menu" format="color"/>
<attr name="color_text_main" format="color"/>
Define your theme color (here, blue and green)
<style name="AppTheme_green" parent="DefaultTheme">
<item name="color_menu">#color/very_dark_green</item>
<item name="color_text_main">#color/very_dark_gray3</item>
</style>
<style name="AppTheme_blue" parent="DefaultTheme">
<item name="color_menu">#color/very_dark_blue</item>
<item name="color_text_main">#color/very_dark_gray1</item>
</style>
Now your current activity can have juste one theme in your AndroidManifest.xml
<activity
android:theme="#style/AppTheme_green"
>
...
</activity>
But you can change it dynamically in your activity
activity.setTheme(R.style.AppTheme_Blue);
I hope this can help you

Related

Override Android background in custom style for one theme but not another

I'm using two themes for my Android application, AppTheme and AppThemeDark. I've set up a custom button style for each in the theme definitions:
<!-- Theme definitions -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<item name="android:buttonStyle">#style/ButtonStyle</item>
...
</style>
<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
...
<item name="android:buttonStyle">#style/ButtonStyleDark</item>
...
</style>
<!-- Button styles -->
<style name="ButtonStyle" parent="#style/Widget.AppCompat.Button">
<item name="android:ellipsize">end</item>
<item name="android:maxLines">2</item>
</style>
<style name="ButtonStyleDark" parent="ButtonStyle">
<item name="android:background">#drawable/gray_button_bg</item>
</style>
Note that my AppTheme button, ButtonStyle, doesn't override the background of Widget.AppCompat.Button, but AppThemeDark's button style inherits ButtonStyle and it changes the background.
Now, I would like to extend that buttonStyle with a new custom style for special buttons, e.g. PrimaryButton. In the AppTheme case, I do not want to change the background of the button. In the AppThemeDark case, i do want to change the background of the button.
I would like to define PrimaryButton and have it either inherit the background (in the case of AppTheme) or use a new background (AppThemeDark). Something like this:
<style name="PrimaryButton">
<item name="android:background">?attr/drawablePrimaryButtonBackground</item>
</style>
But as far as I can tell, there's no way to define an attribute in AppThemeDark as a new drawable and AppTheme as "inherit from parent". Setting to transparent obviously makes the button background in AppTheme transparent.
Is my only option to figure out what drawable is being used for a background in Widget.AppCompat.Button and define it locally?
To answer my own question...
You can dig up the private Android resource and use a local copy to retain the background. That locks you into one specific Android version of the drawable though (unless you copy multiple versions over).
You can set whole styles as attributes if the styles between your two themes are different enough to warrant it:
attrs.xml:
<attr name="stylePrimaryButton" format="reference" />
styles.xml:
<!-- Theme definitions -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
...
<item name="stylePrimaryButton">#style/PrimaryButton</item>
...
</style>
<style name="AppThemeDark" parent="Theme.AppCompat.DayNight.NoActionBar">
...
<item name="stylePrimaryButton">#style/PrimaryButtonDark</item>
...
</style>
<!-- Primary button styles -->
<style name="PrimaryButton">
<!-- no need to override anything -->
</style>
<style name="PrimaryButtonDark">
<item name="android:background">#drawable/dark_background</item>
</style>
layout.xml:
<Button style="?attr/stylePrimaryButton"
...

Specify colors for individual style tags

Is it possible to specify colorPrimary and colorAccent for individual style elments rather than in theme tag
<style name="MyCustomTabLayout" parent="android:Widget">
<item name="colorPrimaryDark">#color/gray900</item>
<item name="colorAccent">#color/gray50</item>
<item name="tabBackground">?attr/colorPrimaryDark</item>
<item name="tabSelectedTextColor">?android:colorAccent</item>
</style>
<style name="MyCustomTabLayout2" parent="android:Widget">
<item name="colorPrimaryDark">#color/gray50</item>
<item name="colorAccent">#color/gray900</item>
<item name="tabBackground">?attr/colorPrimaryDark</item>
<item name="tabSelectedTextColor">?android:colorAccent</item>
</style>
When I try doing this the default theme is applied. Is there a way/better way to do this?
Widgets look up their accent colors etc on the context theme. You can define different themes to hold your styles, and apply them to different layouts using android:theme attribute, if you use the latest appcompat suport library. See https://chris.banes.me/2014/11/12/theme-vs-style/
Citing an example there:
res/values/themes.xml
<style name="RedThemeOverlay" parent="android:ThemeOverlay.Material">
<item name="android:colorEdgeEffect">#FF0000</item>
</style>
res/layout/fragment_list.xml
<ListView
...
android:theme="RedThemeOverlay" />

Android: Theme is not working

I am trying to apply a theme to android activity
themes.xml
<style name="AppBaseTheme" parent="android:Theme.Light"></style>
<!-- Application theme. -->
<style name="CableTheme" parent="AppBaseTheme">
<item name="textViewStyle">#style/Textview</item>
</style>
styles.xml
<style name="Textview" parent="#android:style/Widget.TextView">
<item name="android:textSize">22.0dp</item>
<item name="android:textColor">#android:color/holo_blue_bright</item>
</style>
Attrs.xml
<attr name="textViewStyle" format="reference" />
1) CableTheme is the applicaition theme . I expect all the textview should be in 22dp size and blue in color in the activity.But it is not rendering.
2) I want apply a style like text size 20 to all the textview in my activity . If above is not the correct procedure to apply theme. How can i do it?
It should be
<item name="android:textViewStyle">#style/Textview</item>
the attribute textViewStyle is from the framework. Therefore you have to put in the 'android' namespace before that.
Remove the textViewStyle attribute you defined yourself.

Style selector?

I have two holo based ABS styles, Purple and Lime, users are able to set the theme from settings.
In my layout I have a TextView with a custom textAppearance, I want to change that textAppearance based on the active style.
(if the purple theme is activated the text must be white and if the lime theme is activated the text must be lime)
Is there a way to do that from the XML?
Edit
I'm sorry if the title is misleading.
(if the purple theme is activated the text must be white and if the
lime theme is activated the text must be lime)
Try that:
<style name="PurpleTheme" parent="...">
<!-- define the style for the text appearance here. Following is an example -->
<item name="android:textAppearance">#style/MyWhiteText</item>
</style>
<style name="LimeTheme" parent="...">
<!-- define the style for the text appearance here. Following is an example -->
<item name="android:textAppearance">#style/MyLimeText</item>
</style>
<style name="MyWhiteText" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/white</item>
</style>
<style name="MyWhiteText" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/lime</item>
</style>
Or if you don't want to set the color to all TextViews then do this:
Declare an attribute:
<attr name="myTextViewColor" format="reference" />
Use it like this in your theme:
<style name="PurpleTheme" parent="...">
<item name="myTextViewColor">#color/white</item>
</style>
<style name="LimeTheme" parent="...">
<item name="myTextViewColor">#color/lime</item>
</style>
Now you can set the color of the specific TextView like this:
<TextView
android:textColor="?attr/myTextViewColor"
[...] />

How to apply themes for an exact view?

For example when I define a style tag in XML, all views of all types get that theme. Is there any solution to difference between styles for view types? here is some code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="buttonTheme" parent="android:Theme.Holo">
<item name="android:drawableLeft">#drawable/ic_launcher</item>
</style>
<style name="textTheme" parent="android:Theme.Holo">
<item name="android:textColor">#ff0000</item>
</style>
</resources>
I think there's a small confusion in terms between a style and a theme. You are talking about defining custom styles for a widget in your application. A Theme is a collection of these styles applied globally to an Activity or Application. The custom styles you have created for a button and text view can be applied to a new custom theme so all buttons and text items share the same attributes.
I think what you are looking for is something more like this.
<style name="ApplicationTheme" parent="android:Theme.Holo">
<item name="buttonStyle">#style/MyButtonStyle</item>
<item name="textAppearance">#style/MyTextAppearance</item>
</style>
<style name="MyButtonStyle" parent="android:Widget.Button">
<item name="android:drawableLeft">#drawable/ic_launcher</item>
</style>
<style name="MyTextAppearance" parent="android:TextAppearance">
<item name="android:textColor">#ff0000</item>
</style>
Here, we have created two new styles (one for the button appearance and one for default text appearance), and then applied those as attributes in a new custom theme. You can now apply this theme in your manifest or in View constructors by referencing #style/ApplicationTheme or R.style.ApplicationTheme
You can do this by adding the attribute android:theme="" to the specific activity in your AndroidManifest.xml file
Example:
<activity android:theme="#style/CustomTheme">

Categories

Resources