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.
Related
Per https://material.io/develop/android/theming/typography/, I’ve been customizing my app’s style by modifying the textAppearanceX attributes. Does anyone know which attribute to customize to style an app’s Snackbars or where this is documented?
Thank you.
With the Material Components Library you can customize the textAppearance used by the text and the button through the app theme:
Just use the snackbarButtonStyle and snackbarTextViewStyle attributes to define globally in the app:
<style name="AppTheme" parent="Theme.MaterialComponents.*">
<!-- Style to use for action button within a Snackbar in this theme. -->
<item name="snackbarButtonStyle">#style/Custom.TextButton.Snackbar</item>
<!-- Style to use for message text within a Snackbar in this theme. -->
<item name="snackbarTextViewStyle">#style/Custom.Snackbar.TextView</item>
....
</style>
Then for the button you can define a custom style applying the android:textAppearance attribute
<style name="Custom.TextButton.Snackbar" parent="#style/Widget.MaterialComponents.Button.TextButton.Snackbar">
<item name="android:textAppearance">#style/snackbar_button_textappearance</item>
</style>
It is just an example:
<style name="snackbar_button_textappearance" parent="#style/TextAppearance.MaterialComponents.Button">
<item name="android:textStyle">italic</item>
</style>
For the text you can do something similar with:
<style name="Custom.Snackbar.TextView" parent="#style/Widget.MaterialComponents.Snackbar.TextView">
<item name="android:textAppearance">......</item>
</style>
Pls note:
snackbarButtonStyle attribute requires the version 1.1.0
snackbarTextViewStyle attribute requires the version 1.2.0.
Is it possible to style the new com.google.android.material.textfield.TextInputEditText component without setting it for each component extra?
For example:
For the new TextInputLayout I can set the style globally in the following way:
<style name="Theme.MyTheme" parent="Theme.MaterialComponents.Light.NoActionBar">
.
.
.
<item name="textInputStyle">#style/MyTextInputLayoutStyle</item>
</style>
I expect for the TextInputEditText a similar way for example:
<item name="editTextStyle">#style/MyTextInputEditTextStyle</item>
but it's not working.
Here is a similar post but only for the old design support components.
The TextInputLayout overrides the editTextStyle attribute using the materialThemeOverlay attribute.
For example the Widget.MaterialComponents.TextInputLayout.FilledBox has this default style:
<style name="Widget.MaterialComponents.TextInputLayout.FilledBox" parent="Base.Widget.MaterialComponents.TextInputLayout">
<item name="materialThemeOverlay">
#style/ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox
</item>
....
</style>
<style name="ThemeOverlay.MaterialComponents.TextInputEditText.FilledBox">
<item name="editTextStyle">#style/Widget.MaterialComponents.TextInputEditText.FilledBox</item>
</style>
To globally define you have to define a style for the TextInputLayout extending one of the material themes.
Then you have to use the new materialThemeOverlay attribute. It allows you to override app theme attributes and you can change the editTextStyle attribute.
Something like:
<style name="MyCustomOutlined" parent="Widget.MaterialComponents.TextInputLayout.OutlinedBox">
<item name="materialThemeOverlay">#style/MyThemeOverlayOutlined</item>
</style>
In this way you can change the editTextStyle (app theme attribute) only for this component style.
<style name="MyThemeOverlayOutlined">
<item name="editTextStyle">#style/MyTextInputEditText_outlinedBox</item>
</style>
<style name="MyTextInputEditText_outlinedBox" parent="#style/Widget.MaterialComponents.TextInputEditText.OutlinedBox">
<item name="android:paddingTop">8dp</item>
<item name="android:paddingBottom">8dp</item>
....
</style>
Finally you can assign the MyCustomOutlined to a specific TextInputLayout in the layout:
<com.google.android.material.textfield.TextInputLayout
style="#style/MyCustomOutlined"
.../>
or assign globally in your app theme using:
<style name="AppTheme" parent="Theme.MaterialComponents.Light">
....
<item name="textInputStyle">#style/MyCustomOutlined</item>
</style>
According to this comment, editTextStyle is the correct attribute to set.
https://github.com/material-components/material-components-android/blob/6c70169e8d4ae77429a9c57785e443b2a18b4aa3/lib/java/com/google/android/material/theme/res/values/attrs.xml#L85
See example usage in these styles:
https://github.com/material-components/material-components-android/blob/6c70169e8d4ae77429a9c57785e443b2a18b4aa3/lib/java/com/google/android/material/textfield/res/values/styles.xml#L141
Updated:
Please Set #style/ThemeOverlay.MaterialComponents.TextInputEditText inside your custom TextInputLayoutStyle.
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" />
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).