How to style textviews, edittexts throughout app when theme is extending from Theme.AppCompat.Light.DarkActionBar?
This is not working,
<style name="myTheme" parent="#style/Theme.AppCompat.Light.DarkActionBar">
<item name="android:textViewStyle">#style/myTextViewStyle</item>
<item name="textViewStyle">#style/myTextViewStyle</item>
</style>
<style name="myTextViewStyle" parent="android:Widget.TextView">
<item name="android:layout_marginLeft">5dp</item>
<item name="android:layout_marginRight">5dp</item>
<item name="android:layout_marginTop">5dp</item>
<item name="android:layout_marginBottom">5dp</item>
<item name="android:textColor">#android:color/black</item>
</style>
<!-- Maintain *theme* naming convention Theme.ThemeName. It helps with organization. -->
<style name="Theme.MyApp" parent="Theme.AppCompat.Light.DarkActionBar">
<item name="android:textViewStyle">#style/Widget.MyApp.TextView</item>
<!-- AppCompat does not provide its own variant of textViewStyle attribute. -->
<item name="editTextStyle">#style/Widget.MyApp.EditText</item>
</style>
<!-- Maintain *style* naming convention Widget.ThemeName.WidgetName. -->
<!-- TextView is a simple widget, use the parent provided by platform. -->
<style name="Widget.MyApp.TextView" parent="android:Widget.TextView">
<!-- ... -->
</style>
<!-- EditText parent is provided by AppCompat. -->
<style name="Widget.MyApp.EditText" parent="Widget.AppCompat.EditText">
<!-- ... -->
</style>
As long as your app or activity has android:theme="#style/Theme.MyApp defined in manifest it will work.
Couple of notes:
If you want to provide a default style for another widget try it like so:
Override widgetNameStyle in your theme.
If the attribute doesn't exist, prefix it with android:.
If that doesn't work then it's a custom widget and that's beyond the scope of this post.
Don't override both android:-prefixed and unprefixed variants if they exist! Only one works.
Unprefixed attribute is from AppCompat, use AppCompat style as parent.
Prefixed attribute is from Android SDK, use platform style as parent (TextView and ProgressBar).
Don't mix themes and styles. Themes are context-wide applied to whole hierarchies of views (android:theme atribute). Styles are for widgets (style attribute).
Related
I would like to change the action bar size. I have tried the following coding.
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/CustomActionBar</item>
</style>
<style name="CustomActionBar" parent="#android:style/Widget.Holo.Light.ActionBar">
<!-- <item name="android:background">#drawable/action_bar_style</item> -->
<item name="android:actionBarSize">15dp</item>
<item name="android:background">#drawable/header_bar</item>
</style>
But the action bar size didn't change. Is there another way? I am using api level 11.
Thanks.
Use height attribute, actionBarSize if for something else.
<item name="android:height">#dimen/bar_height</item>
Explanantion:
From source code of ActionBar:
mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
We can see that R.styleable.ActionBar_height is being used for height. Stylable property names are generated as component_attribute (If you have ever used a custom stylable view, you'd have notice this). Hence, Actionbar is the name of component and height is the name of the attribute to use. Since this is a system attribute, hence defined under android namespace.
Update Dec-2014:
AppCompat library is now provided to extend support for latest ActionBar (or Toolbar) and theme support to old android versions. Below is an example of such an application theme /res/values/styles.xml:
<resources>
<!-- Application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="colorPrimary">#color/primary</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">#color/primary_dark</item>
<!-- theme UI controls like checkboxes and text fields -->
<!-- native widgets will now be "tinted" with accent color -->
<item name="colorAccent">#color/accent</item>
<!--Action bar style-->
<item name="android:actionBarStyle">#style/AppTheme.ActionBar</item>
<item name="actionBarStyle">#style/AppTheme.ActionBar</item>
</style>
<style name="AppTheme.ActionBar" parent="Widget.AppCompat.Light.ActionBar">
<item name="android:titleTextStyle">#style/AppTheme.ActionBar.TitleText</item>
<item name="titleTextStyle">#style/AppTheme.ActionBar.TitleText</item>
<item name="android:height">#dimen/bar_height</item>
<item name="height">#dimen/bar_height</item>
</style>
<style name="AppTheme.ActionBar.TitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textSize">#dimen/bar_text_size</item>
<item name="android:textColor">#color/bar_text_color</item>
</style>
</resources>
This style can now be set as app theme by using android:theme="#style/AppTheme" in <application> tag of the AndroidManifest.xml.
Note the use of duplicate entries
<item name="android:actionBarStyle">
<item name="actionBarStyle">
The ones without android namespace are there for supporting both compatibility library and native attributes.Some of these attributes didn't exist under android namespace on older versions and belong to support library.
In some other places, you'll need to use app namespace (xmlns:app="http://schemas.android.com/apk/res-auto"), for example app:showAsAction="always" in menu xml files.
Update Apr 2015
AppCompat Library v22 is also available. Read through the article to know what's new.
Simply put actionBarSize item under MyTheme style, like this:
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarSize">15dp</item>
<item name="actionBarSize">15dp</item>
...
</style>
Explanation:
In R.styleable we see that R.styleable.Theme_actionBarSize is a styleable attribute defined at Theme level.
Also, from source code res/values/styles.xml we see how actionBarSize is used to set height:
<style name="Widget.ActionBar">
...
<item name="android:height">?android:attr/actionBarSize</item>
Add this to the custom theme style XML that you are referencing from your manifest file:
<item name="android:windowTitleSize">58dip</item>
For instance if your manifest file looks something like this:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
**android:theme="#style/AppTheme"** >
Your theme style should be -at least- like this:
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowTitleSize">54dip</item>
</style>
S.D.'s solution does not work for me.
I used AppCompat v-21 library in my case.
And I just add
android:layout_height="#dimen/actionBarSize"
android:minHeight="#dimen/actionBarSize"
to my layout file and it works.
Make sure to add S.D.'s code to styles.xml and then add
android:theme="#style/thin_ab"
to the <application> element in the main manifest. (I'm a noob and it took me about 2 hours to find that out.)
I want to customize a Material chip.
I would think this is how to do it:
<style name="AppTheme" parent="Theme.MaterialComponents.NoActionBar">
.... lots more theme stuff here
<item name="chipStyle">#style/MaterialChips</item>
<item name="chipGroupStyle">#style/MaterialChips</item>
<item name="chipStandaloneStyle">#style/MaterialChips</item>
</style>
<style name="MaterialChips" parent="Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/chips</item>
</style>
None of the tags like chipStyle affect the chips. But if I set app:chipBackgroundColor="#color/chips" in xml it works.
It also works fine like this for other things like say <item name="materialAlertDialogTheme">#style/AlertDialogTheme</item>.
The material documentation (if you can call it that) is really not helping.
Your app theme is correct.
The default style used by Chip component is defined in the app theme by the chipStyle attribute.
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">
<!-- Default style for chip component -->
<item name="chipStyle">#style/Widget.MaterialComponents.Chip.Action</item>
</style>
You can customize this style using for example:
<style name="AppTheme" parent="Theme.MaterialComponents.*">
<!-- Default value for chipStyle -->
<item name="chipStyle">#style/MaterialChips</item>
</style>
<style name="MaterialChips" parent="#style/Widget.MaterialComponents.Chip.Choice">
<!-- ... -->
<item name="chipBackgroundColor">#color/chips</item>
</style>
If you specify the style attribute in your layout, this style overrides the default value.
<com.google.android.material.chip.Chip
style="#style/Widget.MaterialComponents.Chip.Entry"
.../>
In this case the Chip uses the Widget.MaterialComponents.Chip.Entry style.
if you define chip style in layout xml, chip override your theme.
It may work if you clear chip style in layout xml.
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"
...
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" />
I would like to change the action bar size. I have tried the following coding.
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarStyle">#style/CustomActionBar</item>
</style>
<style name="CustomActionBar" parent="#android:style/Widget.Holo.Light.ActionBar">
<!-- <item name="android:background">#drawable/action_bar_style</item> -->
<item name="android:actionBarSize">15dp</item>
<item name="android:background">#drawable/header_bar</item>
</style>
But the action bar size didn't change. Is there another way? I am using api level 11.
Thanks.
Use height attribute, actionBarSize if for something else.
<item name="android:height">#dimen/bar_height</item>
Explanantion:
From source code of ActionBar:
mContentHeight = a.getLayoutDimension(R.styleable.ActionBar_height, 0);
We can see that R.styleable.ActionBar_height is being used for height. Stylable property names are generated as component_attribute (If you have ever used a custom stylable view, you'd have notice this). Hence, Actionbar is the name of component and height is the name of the attribute to use. Since this is a system attribute, hence defined under android namespace.
Update Dec-2014:
AppCompat library is now provided to extend support for latest ActionBar (or Toolbar) and theme support to old android versions. Below is an example of such an application theme /res/values/styles.xml:
<resources>
<!-- Application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light">
<!-- Main theme colors -->
<!-- your app branding color for the app bar -->
<item name="colorPrimary">#color/primary</item>
<!-- darker variant for the status bar and contextual app bars -->
<item name="colorPrimaryDark">#color/primary_dark</item>
<!-- theme UI controls like checkboxes and text fields -->
<!-- native widgets will now be "tinted" with accent color -->
<item name="colorAccent">#color/accent</item>
<!--Action bar style-->
<item name="android:actionBarStyle">#style/AppTheme.ActionBar</item>
<item name="actionBarStyle">#style/AppTheme.ActionBar</item>
</style>
<style name="AppTheme.ActionBar" parent="Widget.AppCompat.Light.ActionBar">
<item name="android:titleTextStyle">#style/AppTheme.ActionBar.TitleText</item>
<item name="titleTextStyle">#style/AppTheme.ActionBar.TitleText</item>
<item name="android:height">#dimen/bar_height</item>
<item name="height">#dimen/bar_height</item>
</style>
<style name="AppTheme.ActionBar.TitleText" parent="TextAppearance.AppCompat.Widget.ActionBar.Title">
<item name="android:textSize">#dimen/bar_text_size</item>
<item name="android:textColor">#color/bar_text_color</item>
</style>
</resources>
This style can now be set as app theme by using android:theme="#style/AppTheme" in <application> tag of the AndroidManifest.xml.
Note the use of duplicate entries
<item name="android:actionBarStyle">
<item name="actionBarStyle">
The ones without android namespace are there for supporting both compatibility library and native attributes.Some of these attributes didn't exist under android namespace on older versions and belong to support library.
In some other places, you'll need to use app namespace (xmlns:app="http://schemas.android.com/apk/res-auto"), for example app:showAsAction="always" in menu xml files.
Update Apr 2015
AppCompat Library v22 is also available. Read through the article to know what's new.
Simply put actionBarSize item under MyTheme style, like this:
<style name="MyTheme" parent="#android:style/Theme.Holo.Light">
<item name="android:actionBarSize">15dp</item>
<item name="actionBarSize">15dp</item>
...
</style>
Explanation:
In R.styleable we see that R.styleable.Theme_actionBarSize is a styleable attribute defined at Theme level.
Also, from source code res/values/styles.xml we see how actionBarSize is used to set height:
<style name="Widget.ActionBar">
...
<item name="android:height">?android:attr/actionBarSize</item>
Add this to the custom theme style XML that you are referencing from your manifest file:
<item name="android:windowTitleSize">58dip</item>
For instance if your manifest file looks something like this:
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
**android:theme="#style/AppTheme"** >
Your theme style should be -at least- like this:
<!-- Application theme. -->
<style name="AppTheme" parent="AppBaseTheme">
<item name="android:windowTitleSize">54dip</item>
</style>
S.D.'s solution does not work for me.
I used AppCompat v-21 library in my case.
And I just add
android:layout_height="#dimen/actionBarSize"
android:minHeight="#dimen/actionBarSize"
to my layout file and it works.
Make sure to add S.D.'s code to styles.xml and then add
android:theme="#style/thin_ab"
to the <application> element in the main manifest. (I'm a noob and it took me about 2 hours to find that out.)