Android style inheritance - android

I have two themes, one has ActionBar and one without. It seems redundant to do duplicate the styles, is there any way to simplify it?
Thanks
<style name="AppTheme.NoActionBar" parent="Theme.AppCompat.Light.NoActionBar">
<item name="colorPrimary">#color/primary_color</item>
<item name="android:windowBackground">#color/bg_color</item>
<item name="colorAccent">#color/accent_color</item>
<item name="colorPrimaryDark">#color/darker_color</item>
<!-- Button style -->
<item name="android:buttonStyle">#style/ButtonStyle</item>
<item name="buttonStyle">#style/ButtonStyle</item>
</style>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/primary_color</item>
<item name="android:windowBackground">#color/bg_color</item>
<item name="colorAccent">#color/accent_color</item>
<item name="colorPrimaryDark">#color/darker_color</item>
<!-- Button style -->
<item name="android:buttonStyle">#style/ButtonStyle</item>
<item name="buttonStyle">#style/ButtonStyle</item>
</style>
<style name="ButtonStyle" parent="Widget.AppCompat.Button">
<item name="android:background">#color/primary_color</item>
</style>

Unfortunately, due to the way that Style/Theme inheritance works, there is no way around this. You could read more about that here:
Android Styles heritage
One option, however, would be to copy the contents of the NoActionBar theme. It turns out that it only contains 2 lines:
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
So your code would look like this
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/primary_color</item>
<item name="android:windowBackground">#color/bg_color</item>
<item name="colorAccent">#color/accent_color</item>
<item name="colorPrimaryDark">#color/darker_color</item>
<!-- Button style -->
<item name="android:buttonStyle">#style/ButtonStyle</item>
<item name="buttonStyle">#style/ButtonStyle</item>
</style>
<!-- NoActionBar theme -->
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
Now you are inheriting the AppTheme attributes as well as getting the NoActionBar behavior. Obviously this is not foolproof if the attributes of NoActionBar change in the future, but it might be a good option for someone with many attributes in their base AppTheme.

Related

Combine applyDayNight() with custom theme overlay?

In androidx you can easily toggle between day/night mode. E.g.:
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
<!-- attributes -->
</style>
And when toggling theme:
AppCompatDelegate.setDefaultNightMode(nightMode);
getDelegate().applyDayNight();
Now, let's say I want to add a minor customization to either the day or the night theme:
<style name="LimeTheme" parent="AppTheme">
<item name="colorPrimary">#color/lime1</item>
<item name="colorPrimaryDark">#color/lime2</item>
<item name="colorControlHighlight">#color/lime3</item>
</style>
How do I accomplish that?
May be you need a folder —— [values-night].
In your theme.xml(or style.xml), you can set the day theme like :
<style name="Theme.MyTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar" >
<item name="minor customization">#style/ThemeOverlay.MyTheme.DayCustom</item>
</style>
In your theme-night.xml(or style-night.xml):
<style name="Theme.MyTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar" >
<item name="minor customization">#style/ThemeOverlay.MyTheme.NightCustom</item>
</style>
And in style,you shoule init these:
<style name="ThemeOverlay.MyTheme.NightCustom" parent="">
<item name="colorPrimary">#color/nightLime1</item>
<item name="colorPrimaryDark">#color/nightLime2</item>
<item name="colorControlHighlight">#color/nightLime3</item>
</style>
<style name="ThemeOverlay.MyTheme.DayCustom" parent="">
<item name="colorPrimary">#color/dayLime1</item>
<item name="colorPrimaryDark">#color/dayLime2</item>
<item name="colorControlHighlight">#color/dayLime3</item>
</style>
The key is in ThemeOverlay, the parent of ThemeOverlay.MyTheme.DayCustom or ThemeOverlay.MyTheme.NightCustom,is "",because the system will automatic recognition it is ThemeOverlay, and just change the style you set,like colorPrimary,colorPrimaryDark...

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.

Android styles: how to change colors in styles.xml

I want to change some colors of android UI elements. But I would prefer to set a default tint color, which applies to all UI elements. I am not sure if this is possible.
If not, I want to set the "tint"-color of some UI elements, as shown below. Can anybody enlighten me?
EDIT
Based on what Entreco suggested:
My styles.xml:
<resources>
<!-- Base application theme. -->
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:textColorPrimary">#color/brown</item>
<item name="android:textColorSecondary">#color/brown</item>
<item name="android:textColorTertiary">#color/brown</item>
<item name="android:textColorPrimaryInverse">#color/brown</item>
<item name="android:textColorSecondaryInverse">#color/brown</item>
<item name="android:textColorTertiaryInverse">#color/brown</item>
<item name="colorPrimary">#color/blue</item>
<item name="colorPrimaryDark">#color/blue</item>
<item name="android:actionBarStyle">#style/MyActionBar</item>
<item name="actionBarStyle">#style/MyActionBar</item>
</style>
<!-- style for the action bar backgrounds -->
<style name="MyActionBar" parent="#style/Widget.AppCompat.Light.ActionBar">
<item name="android:titleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="android:subtitleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="android:background">#color/brown</item>
<item name="titleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="subtitleTextStyle">#style/MyTheme.ActionBar.TitleTextStyle</item>
<item name="background">#color/brown</item>
</style>
<style name="MyTheme.ActionBar.TitleTextStyle" parent="#android:style/TextAppearance">
<item name="android:textColor">#color/brown_light</item>
<item name="android:textSize">24sp</item>
</style>
</resources>
And my values-v21/styles.xml:
<resources>
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:colorPrimary">#color/blue</item>
<item name="android:colorPrimaryDark">#color/blue</item>
<!-- <item name="android:colorAccent">#color/white</item> -->
</style>
</resources>
And in my Manifest:
<application android:theme="#style/AppTheme.Base" >
...
</application>
But the primary color is still the same...???
Starting from Lollipop this is straight-forward thanks to the colorPrimary attribute:
file values/styles.xml:
<!-- Base application theme. -->
<style name="AppTheme.Base" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="colorPrimary">#color/primary</item>
<item name="colorPrimaryDark">#color/primary_dark</item>
</style>
file values-v21/styles.xml:
<style name="AppTheme" parent="AppTheme.Base">
<item name="android:colorPrimary">#color/primary</item>
<item name="android:colorPrimaryDark">#color/primary_dark</item>
<item name="android:colorAccent">#color/white</item>
</style>
Basically, you can define a color pallete for your app, and I believe for your case your want to set the colorPrimary (unverified).
More info on Material colors

Android's Material Design of Toolbar / SupportActionBar

I'm experimenting with the news themes tonight and I'm wondering if anyone knows these fix to this issue.
This appears on the stock Toolbar and even, as seen below, when referring to custom layout file.
It's relatively minor but my OCD eyes go right to it so maybe someone can help. Thanks :)
UPDATE: Inheriting from the correct theme and declaring attributes in pairs (with and without the android: prefix) was the fix!
<!-- Base app theme. -->
<style name="AppTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="android:actionBarStyle">#style/MyActionBar</item>
<item name="actionBarStyle">#style/MyActionBar</item>
</style>
<!-- ActionBar styles. -->
<style name="MyActionBar" parent="Widget.AppCompat.ActionBar">
<item name="android:titleTextStyle">#style/MyActionBarTitleText</item>
<item name="titleTextStyle">#style/MyActionBarTitleText</item>
<item name="android:subtitleTextStyle">#style/MyActionBarSubTitleText</item>
<item name="subtitleTextStyle">#style/MyActionBarSubTitleText</item>
<item name="android:background">#color/blue</item>
<item name="background">#color/blue</item>
</style>
<style name="MyActionBarTitleText" parent="#style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">#color/white</item>
</style>
<style name="MyActionBarSubTitleText" parent="#style/TextAppearance.AppCompat.Widget.ActionBar.Subtitle">
<item name="android:textColor">#color/white</item>
<item name="android:textSize">#dimen/subtitle</item>
</style>
If es0329's answer doesn't work for you, try to replace titleTextStyle by titleTextAppearance. It is working for me:
<style name="MyActionBar" parent="Widget.AppCompat.ActionBar">
<item name="android:titleTextAppearance">#style/MyActionBarTitleText</item>
<item name="titleTextAppearance">#style/MyActionBarTitleText</item>
<item name="android:subtitleTextAppearance">#style/MyActionBarSubTitleText</item>
<item name="subtitleTextAppearance">#style/MyActionBarSubTitleText</item>
<item name="android:background">#color/blue</item>
<item name="background">#color/blue</item>
</style>

change ActionBar Spinner text color

I already read many ways to change spinner textColor in an ActionBar, but I really can't figure it out what is missing to make what I need.
This is how I have my actionbar spinner:
As you can see, I have white text on spinner items. I need to change it to black.
My res/styles file is this one.
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppBaseTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
<item name="android:dropDownListViewStyle">#style/MyDropDownListView</item>
<item name="android:dropDownItemStyle">#style/MyDropDownItemView</item>
<!-- <item name="android:textColor">#color/white</item> -->
</style>
<!-- ActionBar styles -->
<style name="MyDropDownListView" parent="#style/Widget.AppCompat.ListView.DropDown">
<item name="android:background">#color/white</item>
</style>
</resources>
I changed background to white, but now i need to change text to black and I can't do it.
Some one can help me?
I think the easiest way is to create a custom spinner item layout for your spinner, but with only a textview & it's color set to whatever you want it to be.
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:gravity="center"
android:textSize="14sp"
android:textColor="#000000" />
Here is also a post that explains how to do it by changing the xml styles: Android Actionbar navigation spinner text color
UPDATE:
Remove the "android:" part from the xml statments that change something from the appcompat library. In my app it did the trick. So instead of this:
<style name="AppBaseTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
<item name="android:dropDownListViewStyle">#style/MyDropDownListView</item>
<item name="android:dropDownItemStyle">#style/MyDropDownItemView</item>
<!-- <item name="android:textColor">#color/white</item> -->
</style>
You remove the "android:" part:
<style name="AppBaseTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
<item name="dropDownListViewStyle">#style/MyDropDownListView</item>
<item name="dropDownItemStyle">#style/MyDropDownItemView</item>
<!-- <item name="textColor">#color/white</item> -->
</style>
UPDATE 2:
So i'll just post how i style my appcompat apps, so maybe you can see what i don't see. I have 2 folders: resources/values & resources/values-v14.
In the resource/value my style.xml file looks like this:
<style name="Theme.Jamesstyle" parent="#style/Theme.AppCompat.Light">
<item name="actionBarStyle">#style/Actionbar.FlatUi</item>
<item name="actionBarTabStyle">#style/ActionBar.FlatUi.Tabs</item>
<item name="actionBarTabTextStyle">#style/ActionBar.FlatUi.Text</item>
<item name="homeAsUpIndicator">#android:color/transparent</item>
</style>
<style name="Actionbar.FlatUi" parent="#style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
<item name="background">#color/bizzumi_light</item>
<item name="backgroundStacked">#color/bizzumi_red</item>
<item name="backgroundSplit">#color/bizzumi_red</item>
<item name="titleTextStyle">#style/TitleColor</item>
<item name="displayOptions">showHome|homeAsUp|showTitle</item>
</style>
<style name="TitleColor" parent="#style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="textColor">#000099</item>
</style>
And in my resources/values-v14 style.xml file i have:
<style name="Theme.Jamesstyle" parent="#style/Theme.AppCompat.Light">
<item name="android:actionBarStyle">#style/Actionbar.FlatUi</item>
<item name="android:actionBarTabStyle">#style/ActionBar.FlatUi.Tabs</item>
<item name="android:homeAsUpIndicator">#android:color/transparent</item>
<item name="android:actionBarTabTextStyle">#style/ActionBar.FlatUi.Text</item>
</style>
<style name="Actionbar.FlatUi" parent="#style/Widget.AppCompat.Light.ActionBar.Solid.Inverse">
<item name="android:background">#color/bizzumi_light</item>
<item name="android:backgroundStacked">#color/bizzumi_light</item>
<item name="android:backgroundSplit">#color/bizzumi_light</item>
<item name="android:titleTextStyle">#style/TitleColor</item>i
<item name="android:displayOptions">showHome|homeAsUp|showTitle</item><item name="displayOptions">showHome|homeAsUp|showTitle</item></style>
<style name="TitleColor" parent="#style/TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textColor">#000099</item>
</style>
Maybe try this folder structure and create 2 different styles.xml files. Otherwise i'm clueless. Good luck!
`<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppBaseTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<!-- API 14 theme customizations can go here. -->
<item name="android:dropDownListViewStyle">#style/MyDropDownListView</item>
<item name="android:dropDownItemStyle">#style/MyDropDownItemView</item>
<!-- <item name="android:textColor">#color/white</item> -->
</style>
<!-- ActionBar styles -->
<style name="MyDropDownListView" parent="#style/Widget.AppCompat.ListView.DropDown">
<item name="android:background">#color/white</item>
<item name="android:textColor">#000000</item>
</style>

Categories

Resources