I have a dark theme and a light theme in my app where the dark theme extends Theme.AppCompat.NoActionBar and the light theme extends Theme.AppCompat.Light.NoActionBar.
I have a lot of custom attributes in those light and dark theme that i have to duplicate in both those themes.
I was wondering if there is a way to actually have all those attributes in a common place and be used by both light and dark theme.
Example below to make things even more clear:
<style name="MotherThemeDark" parent="Theme.AppCompat.NoActionBar">
<!-- Base application theme common to all sdk versions -->
<!--Colors-->
<item name="colorPrimaryDark">#color/brand_dark</item>
<item name="colorPrimary">#color/brand</item>
<item name="colorAccent">#color/brand_accent</item>
<item name="colorPositive">#color/positive</item>
<item name="colorPositiveDark">#color/positive_dark</item>
<item name="colorNegative">#color/negative</item>
<item name="colorNegativeDark">#color/negative_dark</item>
<item name="colorNegativeLight">#color/negative_light</item>
<item name="colorMedium">#color/medium</item>
....
...Things specific to this theme goes here
....
</style>
<style name="MotherTheme" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Base application theme common to all sdk versions -->
<!--Colors-->
<item name="colorPrimaryDark">#color/brand_dark</item>
<item name="colorPrimary">#color/brand</item>
<item name="colorAccent">#color/brand_accent</item>
<item name="colorPositive">#color/positive</item>
<item name="colorPositiveDark">#color/positive_dark</item>
<item name="colorNegative">#color/negative</item>
<item name="colorNegativeDark">#color/negative_dark</item>
<item name="colorNegativeLight">#color/negative_light</item>
<item name="colorMedium">#color/medium</item>
....
...Things specific to this theme goes here
....
</style>
One of the ways is to put the common attributes in a theme overlay (assuming you are using the AppCompat library), e.g. -
<style name=“MyCustomOverlay” parent=”ThemeOverlay.AppCompat”>
<item name="colorPrimaryDark">#color/brand_dark</item>
<item name="colorPrimary">#color/brand</item>
<item name="colorAccent">#color/brand_accent</item>
<item name="colorPositive">#color/positive</item>
<item name="colorPositiveDark">#color/positive_dark</item>
<item name="colorNegative">#color/negative</item>
<item name="colorNegativeDark">#color/negative_dark</item>
<item name="colorNegativeLight">#color/negative_light</item>
<item name="colorMedium">#color/medium</item>
</style>
and then apply android:theme=”MyCustomOverlay” to your root views. This will override the attributes set in your base theme (e.g. MotherTheme or MotherThemeDark) for the root views and all child views. Works for API 11+.
Reference: https://plus.google.com/+AndroidDevelopers/posts/JXHKyhsWHAH
Although I made the above post as an answer, since it helped me find a solution i will post the actual solution here :
I made the dark theme extend ThemeOverlay.AppCompat.Dark and then applied the motherThemeDark to the root layout of the fragment/activity that i wanted to be themed dark. Under the motherThemeDark i only had attributes that i wanted to override for a dark theme.
<style name="MotherTheme" parent="Theme.AppCompat.NoActionBar">
<!-- Base application theme common to all sdk versions -->
<!--Colors-->
<item name="colorPrimaryDark">#color/brand_dark</item>
<item name="colorPrimary">#color/brand</item>
<item name="colorAccent">#color/brand_accent</item>
<item name="colorPositive">#color/positive</item>
<item name="colorPositiveDark">#color/positive_dark</item>
<item name="colorNegative">#color/negative</item>
<item name="colorNegativeDark">#color/negative_dark</item>
<item name="colorNegativeLight">#color/negative_light</item>
<item name="colorMedium">#color/medium</item>
....
...Things specific to this theme goes here
....
</style>
<style name="MotherThemeDark" parent="ThemeOverlay.AppCompat.Dark">
....
....
...Things specific to this theme goes here
....
</style>
Related
I am using the material components theming for our app. Now we want a custom font, which I managed to apply almost everywhere with the theme below, which uses the various textAppearance... attributes defined by material components.
This works very well, and the theme is also applied to the AlertDialogs almost everywhere -- message text and buttons have the custom font, buttons have the correct accent colors etc.
Only the dialog title keeps the Roboto font, no matter what.
<!-- externalized font name for easier change -->
<string name="font_regular" translatable="false" tools:ignore="ReferenceType">#font/atma_regular</string>
<style name="Theme.App" parent="Theme.MaterialComponents.Light.NoActionBar">
<item name="colorPrimary">#color/colorPrimary</item>
<item name="colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="colorAccent">#color/colorAccent</item>
<item name="android:textColorPrimary">#color/textColorPrimary</item>
<item name="android:textColorSecondary">#color/textColorSecondary</item>
<item name="textAppearanceHeadline1">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline2">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline3">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline4">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline5">#style/TextAppearance.App.Button</item>
<item name="textAppearanceHeadline6">#style/TextAppearance.App.Button</item>
<item name="textAppearanceSubtitle1">#style/TextAppearance.App.Subtitle1</item>
<item name="textAppearanceSubtitle2">#style/TextAppearance.App.Subtitle2</item>
<item name="textAppearanceBody1">#style/TextAppearance.App.Body1</item>
<item name="textAppearanceBody2">#style/TextAppearance.App.Body2</item>
<item name="textAppearanceButton">#style/TextAppearance.App.Button</item>
<item name="android:textAppearanceLarge">#style/TextAppearance.App.Large</item>
<item name="android:textAppearanceMedium">#style/TextAppearance.App.Medium</item>
<item name="android:textAppearanceSmall">#style/TextAppearance.App.Small</item>
</style>
<style name="TextAppearance.App.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1">
<item name="fontFamily">#string/font_regular</item>
<item name="android:fontFamily">#string/font_regular</item>
</style>
...
I tried to define an extra theme for the alert dialogs like so:
<style name="Theme.App" parent="Theme.MaterialComponents.Light.NoActionBar">
...
<item name="alertDialogTheme">#style/Theme.App.AlertDialog</item>
...
</style>
<style name="Theme.App.AlertDialog" parent="Theme.MaterialComponents.Light.Dialog.Alert">
<item name="android:windowTitleStyle">#style/TextAppearance.App.DialogWindowTitle</item>
</style>
<style name="TextAppearance.App.DialogWindowTitle" parent="ThemeOverlay.MaterialComponents.Dialog.Alert">
<item name="fontFamily">#string/font_regular</item>
<item name="android:fontFamily">#string/font_regular</item>
<item name="android:textSize">30sp</item>
</style>
But that resets the colors and fonts everywhere. The only thing that is applied, is the textSize.
It really shouldn't be so hard to achieve this, but I am out of ideas right now. I could apply the font programmatically, but that would be quite ugly.
As you mentioned the AlertDialog created by MaterialAlertDialogBuilder uses the style defined by the textAppearanceSubtitle1 attribute in your app theme.
Otherwise you can change the style used by the AlertDialog using something like:
new MaterialAlertDialogBuilder(MainActivity.this,
R.style.MyTitle_ThemeOverlay_MaterialComponents_MaterialAlertDialog)
.setTitle("Title")
.setMessage("Message......")
.setPositiveButton("ok", null)
.setNegativeButton("Cancel", null)
.show();
In your style you have to customize the materialAlertDialogTitleTextStyle attribute:
<style name="MyTitle_ThemeOverlay.MaterialComponents.MaterialAlertDialog" parent="#style/ThemeOverlay.MaterialComponents.MaterialAlertDialog">
<item name="materialAlertDialogTitleTextStyle">#style/MyTitle_MaterialAlertDialog.MaterialComponents.Title.Text</item>
</style>
<style name="MyTitle_MaterialAlertDialog.MaterialComponents.Title.Text" parent="#style/MaterialAlertDialog.MaterialComponents.Title.Text">
<item name="android:textAppearance">#style/MyTitle_TextAppearance.MaterialComponents.Subtitle1</item>
</style>
<style name="MyTitle_TextAppearance.MaterialComponents.Subtitle1" parent="TextAppearance.MaterialComponents.Subtitle1">
<item name="fontFamily">....</item>
<item name="android:fontFamily">....</item>
<item name="android:textStyle">.....</item>
</style>
Thanks to your question I realized that I was using the incorrect attribute to assign the title style (android:titleTextAppearance instead of android:windowTitleStyle).
It looks like your issue has been fixed in the meantime, as your exact code seems to work for me as of today.
I searched google but can not find solution.I need to define different styles for Tablayout for themes.I figure it out how to include my Toolbar style but can not make it work because of Base.Widget.Design.TabLayout.When I define it as a name it works but I can only use it for one style.When I define it as parent and include it to my theme with android:tabWidgetStyle it does not work
As a parent(which does not work)
<style name="tabayout" parent="Base.Widget.Design.TabLayout">
<item name="tabSelectedTextColor">#color/white</item>
<item name="tabIndicatorColor">#color/deep_orange_300_colorAccent</item>
<item name="tabBackground">#color/deep_orange_300_colorAccent</item>
</style>
Second(which works but I can only use it once, but I need to define 14 style)
<style name="Base.Widget.Design.TabLayout" parent="android:Widget">
<item name="tabSelectedTextColor">#color/white</item>
<item name="tabIndicatorColor">#color/red_200_colorAccent</item>
<item name="tabBackground">#color/red_200_colorAccent</item>
<item name="tabTextColor">#color/red_200_colorPrimaryDark</item>
</style>
Edit
I want to style TabLayout for specific custom theme.I want to make Toolbar background textColor etc for chosen colour by user. So I used Base.Widget.Design.TabLayout as a name to style TabLayout and include it with android:tabWidgetStyle it worked.But when I use it as parent it does not work.Here My Theme
This works.But when I define Base.Widget.Design.TabLayout as a parent it does not work.
<style name="AppTheme_red_200" parent="Theme.AppCompat.Light.NoActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">#color/red_200_colorPrimary</item>
<item name="colorPrimaryDark">#color/red_200_colorPrimaryDark</item>
<item name="colorAccent">#color/red_200_colorAccent</item>
<item name="android:tabWidgetStyle">#style/Base.Widget.Design.TabLayout</item>
<item name="android:textColor">#color/red_400_colorPrimaryDark</item>
</style>
<style name="Base.Widget.Design.TabLayout" parent="">
<item name="tabSelectedTextColor">#color/white</item>
<item name="tabIndicatorColor">#color/red_200_colorAccent</item>
<item name="tabBackground">#color/red_200_colorAccent</item>
<item name="tabTextColor">#color/red_200_colorPrimaryDark</item>
</style>
I saw a lot of modern beautiful apps in the Play Store that use image as background. I decided to use this solution in my application. I develop for minimum API 21 Android 5.0. I prepared image 1920x1080 for xxhdpi Nexus 5 AVD.
I use material light theme. Here is my modified theme definition xml
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light">
<!-- Customize your theme here. -->
<item name="android:colorPrimary">#color/colorPrimary</item>
<item name="android:colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="android:colorAccent">#color/colorAccent</item>
<item name="android:background">#drawable/parquet</item>
<item name="android:actionBarStyle">#style/transparentActionBar</item>
<item name="android:statusBarColor">#android:color/transparent</item>
</style>
<style name="transparentActionBar" parent="android:Widget.Material.Light.ActionBar">
<item name="android:background">#android:color/transparent</item>
</style>
When I run application I see that each view uses its own scaled copy of theme image. My custom defined style 'transparentActionBar' has no effect on action bar. Only behind status bar I see something like original image. Is it possible to define all views transparency via XML to make visible only screen background image? If no, tell please what is right approach to the solution of this problem.
Regards.
This code does exact what I want
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="android:Theme.Material.Light">
<!-- Customize your theme here. -->
<item name="android:colorPrimary">#color/colorPrimary</item>
<item name="android:colorPrimaryDark">#color/colorPrimaryDark</item>
<item name="android:colorAccent">#color/colorAccent</item>
<item name="android:statusBarColor">#android:color/transparent</item>
<item name="android:windowBackground">#drawable/parquet</item>
<item name="android:actionBarStyle">#style/ActionBarStyle.Transparent</item>
</style>
<style name="ActionBarStyle.Transparent" parent="android:Widget.Material.Light.ActionBar">
<item name="android:background">#null</item>
</style>
I am doing a personal theme to use holo widget in 2.3 android.
I did this:
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="AppThemes" parent="#style/Theme.Sherlock">
<item name="android:editTextStyle">#style/EditTextAppTheme</item>
<item name="android:checkboxStyle">#style/CheckBoxAppTheme</item>
<item name="android:radioButtonStyle">#style/RadioButtonAppTheme</item>
<item name="android:buttonStyle">#style/ButtonAppTheme</item>
<item name="android:imageButtonStyle">#style/ImageButtonAppTheme</item>
<item name="android:spinnerStyle">#style/SpinnerAppTheme</item>
<item name="android:dropDownSpinnerStyle">#style/SpinnerAppTheme.DropDown</item>
<item name="android:spinnerDropDownItemStyle">#style/SpinnerDropDownItemAppTheme</item>
</style>
</resources>
the problem is that widgets don't take the correct style but take the default style. I tried to force assign the #style/EditTextAppTheme at an edittext and it worked.. so the problem is that the theme don't apply.
any idea?
update: the theme apply and work good..the solo problem is some edittext inside a dialog that show with the standard theme
To get the holo theme style in an App for API 10 and below, you can use HoloEverywhere. It's well integrated with ActionBarSherlock. ActionBarSherlock is included as a subproject. https://github.com/ChristopheVersieux/HoloEverywhere
If you want to use a customized Theme you have to set these style attributes in your Application theme. Then apply this theme to the whole App or to a single Activity by defining it in the manifest or setting it programmaticaly in the onCreate() method.
For example(for ABS):
<style name="Theme.myStyle" parent="Theme.Sherlock">
<item name="android:editTextStyle">#style/EditTextAppTheme</item>
<item name="android:checkboxStyle">#style/CheckBoxAppTheme</item>
<item name="android:radioButtonStyle">#style/RadioButtonAppTheme</item>
<item name="android:buttonStyle">#style/ButtonAppTheme</item>
<item name="android:imageButtonStyle">#style/ImageButtonAppTheme</item>
<item name="android:spinnerStyle">#style/SpinnerAppTheme</item>
<item name="android:dropDownSpinnerStyle">#style/SpinnerAppTheme.DropDown</item>
<item name="android:spinnerDropDownItemStyle">#style/SpinnerDropDownItemAppTheme</item>
</style>
And then set this theme to your Application or your Activity in the Manifest with:
android:theme="#style/Theme.myStyle"
or programmatically:
setTheme(R.style.Theme.myStyle);
I am currently making an app (Android 1.6) that can change between two different themes.
I made a custom theme that takes the Android light theme as a parent!
The trouble is that when I switch to white theme my text is not drawn but if I select something I can see the text. Furthermore when I switch themes my titleText, previous and next are the same as in my dark theme.
Here is the code I use for the theme:
<style name="Theme.White" parent="android:Theme.Light">
<item name="android:colorBackground">#color/text_color_dark</item>
<item name="android:textColor">#color/text_color_dark</item>
<item name="textPrev">#style/text_prev</item>
<item name="textRegular">#style/text_regular</item>
<item name="textTitle">#style/text_title</item>
<item name="textNext">#style/text_next</item>
<item name="pageBack">#style/page_back</item>
<item name="whiteBack">#style/white_back</item>
<item name="android:textColorPrimaryInverse">#android:color/primary_text_light</item>
</style>
</resources>
This is my style:
<style name="text_prev">
<item name="android:textColor">#color/text_color</item>
</style>
<style name="text_next">
<item name="android:textColor">#color/default_text_color_2</item>
</style>
<style name="text_regular">
<item name="android:textColor">#color/text_color_dark</item>
</style>
<style name="text_title">
<item name="android:textColor">#color/text_color_dark</item>
</style>
<style name="page_back">
<item name="android:background">#drawable/white_background</item>
</style>
<style name="white_back">
<item name="android:background">#drawable/white_container</item>
<item name="android:padding">10sp</item>
</style>
I use two more resources that are in my res/drawable folder. Everything works fine in the standard theme, but as soon as I switch to my light theme my text disappears.
Is there something that I'm doing wrong?
From your code snippet above you're setting both background and text to the same color i.e. "color/text_color_dark", these should be different.
<item name="android:colorBackground">#color/text_color_dark</item>
<item name="android:textColor">#color/text_color_dark</item>