Android - Overriding a Style per Theme - android

Is there a way to change a style based on what theme is is set on an activity? for example, suppose my activity has a textview with a style set to TextViewStyle
<TextView
style="#style/TextViewStyle"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Text"/>
This is my TextViewStyle
<style name="TextViewStyle" parent="android:style/Widget.TextView">
<item name="android:textStyle">bold</item>
<item name="android:textSize">8sp</item>
<item name="android:textColor">#android:color/holo_blue_dark</item>
</style>
In my Styles.xml I have two themes
<style name="AppThemeLight" parent="android:Theme.Material.Light">
</style>
<style name="AppThemeDark" parent="android:Theme.Material">
</style>
Now, when I have my theme set to Dark, I want this theme to override some values I set in my TextViewStyle. How could I do this? I tried the following, but It does not work
<!-- Override TextViewStyle style for AppThemeLight-->
<style name ="AppThemeLight.TextBlockStyle" parent="#style/TextBlockStyle">
<item name="android:textColor">#color/my_purple</item>
<item name="android:textSize">20sp</item>
</style>
<!-- Override TextViewStyle style for AppThemeDark-->
<style name ="AppThemeDark.TextBlockStyle" parent="#style/TextBlockStyle">
<item name="android:textColor">#color/my_green</item>
<item name="android:textSize">40sp</item>
</style>

Ok here is how I achieved this, 1 hour after posting the question! Might be helpful for someone else!
First in attrs.xml I defined the following :
<attr name="textBlockStyle" format="reference"/>
Then in the style.xml
<style name="TextBlockStyle" parent="android:style/Widget.TextView">
<item name="android:textStyle">bold</item>
<item name="android:textSize">8sp</item>
<item name="android:textColor">#android:color/holo_blue_dark</item>
</style>
<style name="AppThemeLight" parent="android:Theme.Material.Light">
<item name="android:windowNoTitle">true</item>
<item name="textBlockStyle">#style/AppThemeLightTextBlockStyle</item>
</style>
<style name="AppThemeDark" parent="android:Theme.Material">
<item name="android:windowNoTitle">true</item>
<item name="textBlockStyle">#style/AppThemeDarkTextBlockStyle</item>
</style>
<!-- Override TextBlockStyle style for AppThemeLight -->
<style name ="AppThemeLightTextBlockStyle" parent="#style/TextBlockStyle">
<item name="android:textColor">#color/my_purple</item>
<item name="android:textSize">20sp</item>
</style>
<!-- Override MyButton style for AppThemeDark -->
<style name ="AppThemeDarkTextBlockStyle" parent="#style/TextBlockStyle">
<item name="android:textColor">#color/my_green</item>
<item name="android:textSize">40sp</item>
</style>
Notice how I use the attribute I defined to reference a style
<item name="textBlockStyle">#style/AppThemeLightTextBlockStyle</item>
Finally, on my element I set the style like this "style="?textBlockStyle" :
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
style="?textBlockStyle"
android:text="...."
android:gravity="center" />
When I set my activity theme to Dark or Light, the correct textButtenStyle will be used

Add a textStyle element to your activity style and make it equal to the desired style, then when the activity is loaded all textViews inside will have the style specified inside its theme unless you override it in your textView

Try something like
<item name="android:textAppearance">#style/yourTextViewStyle</item>
Inside your activity style

Related

Dropdown Spinner text color

So I have a spinner that I'm trying to apply a style to. I have a activity theme
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
And a spinner
<Spinner
android:id="#+id/spinner"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:entries="#array/entries"
I want the text of the spinner items to appear as white and to do so with xml styling. If I set android:textColor in AppTheme, everything works fine.
However this applies to other elements as well.
I have tried the following attribues in AppTheme. None of them have worked.
<item name="android:spinnerDropDownItemStyle">#style/SpinnerItem</item>
<item name="android:dropDownItemStyle">#style/SpinnerItem</item>
<item name="android:spinnerItemStyle">#style/SpinnerItem</item>
<style name="SpinnerItem">
<item name="android:textColor">#android:color/white</item>
</style>
Any help is appreciated.
You can change your AppTheme like this:
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:spinnerStyle">#style/AppTheme.Spinner</item>
<item name="android:spinnerDropDownItemStyle">#style/AppTheme.DropDownSpinner</item>
</style>
<style name="AppTheme.Spinner" parent="Widget.AppCompat.Spinner">
<item name="android:textColor">#color/white</item>
</style>
<style name="AppTheme.DropDownSpinner" parent="Widget.AppCompat.DropDownItem.Spinner">
<item name="android:textColor">#color/white</item>
</style>

buttonStyle not working for 22.1.1

I´m Using com.android.support:appcompat-v7:22.1.1
This attribute android:buttonStyle is not setting that style for every button, I need to set android:theme="#style/AppTheme.Button" manually on each button.
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="android:buttonStyle">#style/AppTheme.Button</item>
</style>
What do I need to do to set a general style for it?
Use buttonStyle insteadof android:buttonStyle in your theme
Similar to #danielgomezrico answer but without having two style files:
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<!-- android:buttonStyle for v21+ and buttonStyle for the rest -->
<item name="buttonStyle">#style/MyCustomButton</item>
<item name="android:buttonStyle">#style/MyCustomButton</item>
<item name="colorButtonNormal">#color/my_color_accent</item>
</style>
<style name="MyCustomButton" parent="Base.Widget.AppCompat.Button">
<item name="android:textColor">#ffffff</item>
</style>
I ended up setting background color with colorButtonNormal attribute and other style attributes with buttonStyle.
values/style.xml:
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/my_color_primary</item>
<item name="colorPrimaryDark">#color/my_color_primary_dark</item>
<item name="colorAccent">#color/my_color_accent</item>
</style>
<style name="AppTheme.Base">
<item name="colorButtonNormal">#color/my_color_accent</item>
<item name="buttonStyle">#style/Button</item>
</style>
<style name="Button" parent="Base.Widget.AppCompat.Button">
<item name="android:textColor">#color/my_color_white</item>
</style>
values-v21/style.xml
<style name="AppTheme.Base">
<item name="android:colorButtonNormal">#color/my_color_accent</item>
<item name="android:buttonStyle">#style/Button</item>
</style>
And then all the buttons have the background/text color I wanted without setting style on each one.

Using A Custom Attribute That Is In A Style With A View

Lets say I have a custom attribute in a few styles like so:
<style name="Theme1" parent="android:Theme.Holo">
<item name="textViewBackground">#000022</item>
<item name="android:background">#000000</item>
</style>
<style name="Theme2" parent="android:Theme.Holo">
<item name="textViewBackground">#AA2200</item>
<item name="android:background">#000000</item>
</style>
Can I then reference that in a standard view like a TextView? Something like:
<TextView
android:id="#+id/txtNumber"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#CurrentTheme.textViewBackground"
android:text="Number" />
You need to define a TextView style, like this:
<style name="Theme1" parent="android:Theme.Holo">
<item name="android:textViewStyle">#style/TextViewStyle1</item>
<item name="android:background">#000000</item>
</style>
<style name="Theme2" parent="android:Theme.Holo">
<item name="android:textViewStyle">#style/TextViewStyle2</item>
<item name="android:background">#000000</item>
</style>
<style name="TextViewStyle1" parent="#android:style/Widget.TextView">
<item name="android:background">#000022</item>
</style>
<style name="TextViewStyle2" parent="#android:style/Widget.TextView">
<item name="android:background">#AA2200</item>
</style>
Then you won't even need to set the android:background attribute on each TextView in your xml, it will apply to all TextViews that do not specify a different background.

How to set ListView style in the resource?

I want to set the ListView style in the Theme, so that all the ListView of the Application will inherit the style. My code looks like this:
style.xml
<!-- Light Theme of the Application -->
<style name="AppTheme.Light" parent="Theme.Sherlock.Light">
<item name="actionBarStyle">#style/ActionBar.Green</item>
<item name="android:absListViewStyle">#style/AbsListViewStyle.Light</item>
</style>
<style name="AbsListViewStyle.Light" parent="android:style/Widget.AbsListView">
<item name="background">#color/background_light</item>
<item name="android:divider">#color/light_gray</item>
<item name="android:dividerHeight">1dp</item>
<item name="android:listSelector">#drawable/actionbar_background_green</item>
<item name="android:drawSelectorOnTop">false</item>
<item name="android:cacheColorHint">#00000000</item>
</style>
I set the theme of the Activity in the AndroidManifest.xml.
But it seems that the style is not applied to the ListView.
Why is that?
Finally I got the reason, I should use android:listViewStyle attribute instead of absListViewStyle:
style.xml
<!-- Light Theme of the Application -->
<style name="AppTheme.Light" parent="Theme.Sherlock.Light">
<item name="actionBarStyle">#style/ActionBar.Green</item>
<item name="android:listViewStyle">#style/ListViewStyle.Light</item>
</style>
<style name="ListViewStyle.Light" parent="android:style/Widget.ListView">
<item name="background">#color/background_light</item>
<item name="android:divider">#color/light_gray</item>
<item name="android:dividerHeight">1dp</item>
<item name="android:listSelector">#drawable/actionbar_background_green</item>
<item name="android:drawSelectorOnTop">false</item>
<item name="android:cacheColorHint">#00000000</item>
</style>
In this way I can apply ListView style in the Theme xml.
You need to set it on your ListView in xml for list view add:
style="#style/AbsListViewStyle.Light"

insert a custom style inside two different theme

I want to add a custom style that is for example purple in one theme and red in one other theme.
<style name="subtitle_layout" parent="#android:style/Theme.Holo.Light">
<item name="android:background">#color/purple</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">40sp</item>
</style>
<style name="subtitle_layout2" parent="#android:style/Theme.Holo.Light">
<item name="android:background">#color/black</item>
<item name="android:layout_width">fill_parent</item>
<item name="android:layout_height">80sp</item>
</style>
<style name="Theme1" parent="android:Theme.Holo.Light">
<item name="android:textColor">#color/black</item>
<item name="#style/subtitle_layout">#style/subtitle_layout</item>
</style>
<style name="Theme2" parent="android:Theme.Holo.Light">
<item name="android:textColor">#color/white</item>
<item name="#style/subtitle_layout">#style/subtitle_layout2</item>
</style>
The change of theme works because i see the change of text color, but instead of android:textColor i would like to put a style instead. But it doesn't work.
I guess you are trying to inherit existing styles to your theme, am I right? You can just set the style as your parent theme:
<style name="Theme1" parent="#style/subtitle_layout">
<item name="android:textColor">#color/black</item>
</style>

Categories

Resources