https://material.io/develop/android/theming/shape/
The site describes how to customize a MaterialCardView, but when I choose Widget.MaterialComponents.MaterialCardView as my parent in my style file it can't be found.
I tried to do it with Widget.MaterialComponents.CardView, but it got me a grey background for my card. I could fix the grey background with app:cardForegroundColor which works fine for most cases, but when I use the MaterialCardView in some special cases like as a BottomSheet, the build-in animations for the automatic corner transition makes the grey background again visible.
I'm anyway not happy with app:cardForegroundColor because I think it shouldn't be used when possible.
In the end I could fix all of the problems by choosing the parent as Theme.MaterialComponents,
but I would still like to know what I did wrong or how it should actually be done.
I used androidx and com.google.android.material:material:1.1.0
Style: must have as parent a MaterialComponents theme if you are using AndroidX
<style name="CardActivityTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">#color/colorAccentX</item>
</style>
To create a beatiful outlined material card in Google style, create it in your activity XML layout:
<com.google.android.material.card.MaterialCardView
android:id="#+id/card0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardBackgroundColor="#FFF"
app:strokeWidth="1dp"
app:strokeColor="DADCE0"
app:cardElevation="0dp"
app:cardCornerRadius="8dp">
</com.google.android.material.card.MaterialCardView>
I have made some attributes hardcoded to give you directly the colors.
Result:
If you prefer the normal elevated card, and not the outlined use this:
<com.google.android.material.card.MaterialCardView
android:id="#+id/card0"
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:cardUseCompatPadding="true"
app:cardBackgroundColor="#FFF"
app:cardElevation="1dp"
app:cardCornerRadius="8dp">
</com.google.android.material.card.MaterialCardView>
Notice that i have deleted from the previous one the attributes app:strokeWidth and app:strokeColor.
Finally, if you want to create an animation like in the GIF you have posted, I strongly recommend to use Motion Layout.
Related
I recently moved from using custom card components to material design 3 cards. To my surprise, the ripple color, when pressing on the card, changes the content color. I tried this on the catalog project of the material-design-components repository and the card behaves the same way. My current code for changing the ripple color and the card background:
<style name="Widget.App.Card.Filled" parent="Widget.Material3.CardView.Filled">
<item name="rippleColor">#4D4D4D</item>
<item name="cardBackgroundColor">#android:color/transparent</item>
</style>
I also got a demo showing this behavior: https://i.imgur.com/t4WW4CY.mp4. The font color changes to a light gray based on the ripple effect. I am also using material buttons but there the ripple effect is not affecting the content. I am using the version 1.5.0-rc01.
Does anyone have an idea if that is intended and how I can only change the background color on press using the attributes given by the material design components.
Update:
My card view XML (its the one from the material-components github + custom style):
<com.google.android.material.card.MaterialCardView
style="#style/Widget.App.Card.Filled"
android:id="#+id/card"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="0.4"
android:layout_margin="16dp"
android:clickable="true"
android:focusable="true"
app:contentPadding="#dimen/cat_card_content_padding">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="#string/cat_card_states_card_content"
android:textAppearance="?attr/textAppearanceBody1"/>
</com.google.android.material.card.MaterialCardView>
I think this is happening because of the ripple color applying to the foreground instead of background. So yeah this is intended and i don't think you can change that.
Have a look at the source code : MaterialCardViewHelper.java
Note : This does not happen in buttons bcoz buttons applies ripple to the background instead of foreground.
Source code for button : MaterialButtonHelper.java
I am creating an Android app and I wanted to use extended floating action button so I added this code to my activity:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/new_game_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|center"
android:text="#string/main_new_game"
android:backgroundTint="#color/colorAccent"
app:icon="#drawable/ic_play_arrow_24px"/>
The button looks exactly how it is supposed to, except that it does not have ripple effect on click.
How can I add the ripple effect? I took the code straight from https://material.io/develop/android/components/floating-action-button/#extended-fabs and it looks like the ripple should be there by default, but it does not work in my app. I have tried to create new project where I only set up the Material Components (https://material.io/develop/android/docs/getting-started/) and the button still does not have ripple effect. So it does not seem to be a problem with my project setup.
I have also tried setting the app:rippleColor attribute, setting android:clickable="true" android:focusable="true" to no avail. Only thing that sort of worked was setting android:foreground="?attr/selectableItemBackground", but the ripple effect was masked to rectangle instead of the shape of the extended FAB. Also setting the foreground is not very good approach since it is only supported on API 23 and higher and I am targeting API 21.
You are supposed to use this attribute app:rippleColor
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:id="#+id/new_game_fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="16dp"
android:layout_gravity="bottom|center"
android:text="#string/main_new_game"
android:backgroundTint="#color/colorAccent"
app:icon="#drawable/ic_play_arrow_24px"
app:rippleColor="#color/colorPrimary" />
The default style of the ExtendedFloatingActionButton has a default rippleColor selector based on the colorOnSecondary.
Check in your app theme this color.
In any case you can override the color using:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
app:rippleColor="#color/my_selector" />
Or you can override the colorOnSecondary in your ExtendedFloatingActionButton using:
<com.google.android.material.floatingactionbutton.ExtendedFloatingActionButton
android:theme="style/ExFabOverlay" />
with:
<style name="ExFabOverlay">
<item name="colorOnSecondary">#color/my_color</item>
</style>
Final note: use app:backgroundTint instead of android:backgroundTint.
I'm following google's excellent blog post to make a dark theme for my app, but I don't see any reference on how I get the elevation effects on my views(buttons, app bar, etc) to work. For example when I set my app theme to
<style name="AppTheme" parent="Theme.AppCompat.DayNight.NoActionBar">
and make a button or a card like so:
<Button
android:id="#+id/keypadOne"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="#color/surface"
android:elevation="01dp"
android:text="#string/one"
android:textColor="#color/onSurface"
android:textSize="36sp" />
I would expect to see the effect that makes the object appear lighter due to the semi-transparent white overlay used in dark themes to imply elevation or being closer to a light source than the background. Instead, my buttons,action bar, etc, are the same color as the background and therefore invisible.
My questions are:
Do I have to implement this elevation functionality manually or is that provided by the Material library?
If I get this working automatically for Android 10+ will I have to implement a manual solution for backwards compatibility on versions 9 and earlier?
I've found the solution. In order to achieve the overlay tinting effect on elevation for CardViews you have to use the Material lib's special object that contains this functionality: MaterialCardView. Once you use this CardView, set it's
app:cardElevation attribute to change the white overlay mentioned in the google blog post on Dark Mode I linked above.
For example, my CardView looks like this now:
<com.google.android.material.card.MaterialCardView
android:id="#+id/testCard"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="18dp" app:cardCornerRadius="4dp" />
Note that this special elevation attribute is only available for MaterialCardViews, despite other views like Toolbars having a Material version.
First make sure your using material components library theme and DayNight variant like this
<style name="AppTheme" parent="Theme.MaterialComponents.DayNight.NoActionBar">
this should automatically change surface color for AppBarLayout, Toolbar and MaterialCardView but if you want to set this auto surface color change based on elevation for others view set your
android:background="?attr/colorSurface" or in case of MaterialCardView use this app:cardBackgroundColor="?attr/colorSurface" and apply elevation with
android:elevation="4dp" or in some cases without android namespace elevation="4dp" or in case of MaterialCardView use this app:cardElevation="4dp"
I have a chip with 100dp of width but the text is not centered how I can center the text.
I use androidx with material library, I've tried put android:textAlignment="center" and android:gravity="center" but not work
<com.google.android.material.chip.Chip
android:id="#+id/chip"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="7:00" />
I have this
I want this
just now I faced with the same problem, and I solved it by set a chip property: android: textAlignment = "center". I tested your example and it works fine too, here the code that I tested:
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.google.android.material.chip.Chip
android:id="#+id/chip"
style="#style/Widget.MaterialComponents.Chip.Choice"
android:layout_width="100dp"
android:layout_height="wrap_content"
android:text="7:00"
android:textAlignment="center"/>
</FrameLayout>
Also make sure that you don't set or change a chip's text alignment somewhere in your code.
The short answer:
Chips aren't meant to be used the way you are trying to use them. They are supposed to wrap your content. Therefore there isn't a clean way to align the text in the center.
There is a workaround tho, you can use Chip_textEndPadding and Chip_textStartPadding attributes, which will be kinda awkward I guess.
I don't really know what you are trying to achieve, I mean, what is your why? Is it a button? Is it suppose just to show some text?
Please describe the feature, or at least, part of it.
Anyway:
According to the material design guidelines
Chips allow users to enter information, make selections, filter content, or trigger actions. Chips should appear dynamically as a group of multiple interactive elements. Unlike buttons, which should be a consistent and familiar call to action, one that a user expects to appear as the same action in the same general area.
Does your feature as anything to do with this?
In case you want a clickable, circular component you can simply use material button.
There is a similar question that was asked at github.
as others said you can use textAlignment ...but i wanted to tell you that if your using a custom font it wont be perfectly vertically aligned. you can check here for explanation.
so i would make a custom style that inherits from chip styles and set the font padding for usage like this:
<style name="customStyle" parent="#style/Widget.MaterialComponents.Chip.Choice">
<item name="chipBackgroundColor">#color/white</item>
******* <item name="android:includeFontPadding">true</item> *************
</style>
then for the text appearance you can make another style:
<style name="CustomChipTextAppearance" parent="TextAppearance.MaterialComponents.Chip">
<item name="android:fontFamily">?attr/myFont</item>
<item name="android:textAlignment">center</item>
</style>
dont forget to force a bridge theme in xml:
<com.google.android.material.chip.Chip xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
style="#style/customStyle"
**** android:theme="#style/Theme.MaterialComponents.Bridge" ****
***** android:textAppearance="#style/CustomChipTextAppearance" *******
app:chipMinHeight="38dp"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
app:chipStrokeWidth="2dp"
app:rippleColor="#android:color/transparent"
tools:chipText="my chip" />
Use isTextAlignmentResolved,
For example, chipname.isTextAlignmentResolved() to do this programmatically.
I'm using the new material components com.google.android.material:material with android x but I can't set a custom background to the button.
I know that I can use app:backgroundTint to change the color
but the default background has some padding that I want to get rid of, and the old way of using android:background to set my own background but this is no longer working.
I looked at the docs but can't find any mention to this change.
In the Material Components Library, the MaterialButton has a default style with insetBottom and insetTop with a value of 6dp.
You can change it using:
<com.google.android.material.button.MaterialButton
android:insetTop="0dp"
android:insetBottom="0dp"
../>
If you want to change the background color you can use the app:backgroundTint attribute or you can override some theme attributes from a default style then you can use new materialThemeOverlay attribute.
In your case you can do something like:
<style name="MtButtonStyle"
parent="Widget.MaterialComponents.Button">
<item name=“materialThemeOverlay”>#style/GreenButtonThemeOverlay</item>
</style>
<style name="GreenButtonThemeOverlay">
<item name="colorPrimary">#color/green</item>
</style>
Finally starting with the version 1.2.0-alpha06 you can use the android:background attribute in the MaterialButton.
<MaterialButton
app:backgroundTint="#null"
android:background="#drawable/button_drawable"
... />
The documentation for the MaterialButton class says:
Do not use the android:background attribute. MaterialButton manages its own background drawable, and setting a new background means MaterialButton can no longer guarantee that the new attributes it introduces will function properly. If the default background is changed, MaterialButton cannot guarantee well-defined behavior.
However, the GitHub readme says:
Note: MaterialButton is visually different from Button and AppCompatButton. One of the main differences is that AppCompatButton has a 4dp inset on the left and right sides, whereas MaterialButton does not.
This mentions only left/right inset, but the Attributes section of the readme shows that all four insets are supported:
So you could add these attributes to your <MaterialButton> tag:
android:insetTop="0dp"
android:insetBottom="0dp"
Looking at https://medium.com/#velmm/material-button-in-android-e4391a243b17 I found that app:backgroundTint (and app:backgroundTintMode) works. It changes a color, but not a drawable selector.
Also you can replace <Button with <android.widget.Button.
If you want to use gradient drawable as MaterialButton's background,
set Your MaterialButton as below:
<com.google.android.material.button.MaterialButton
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:backgroundTint="#null"
android:background="#drawable/group_47"
app:layout_constraintEnd_toEndOf="#+id/input_password"
app:layout_constraintStart_toStartOf="#+id/input_password"
app:layout_constraintTop_toBottomOf="#+id/input_password" />
If you wish to keep your
android:background="#drawable/button_background"
And have MaterialButton respect it, then you must set
app:backgroundTint="#null"
app:backgroundTintMode="add" // it doesn't matter the value, but it must be set
Please note that you can also use app:background instead, although I've noticed enough breaking changes that I still prefer the method above.
I face the same issue when I use state drawable in a Button but It does not change the background of the button. After searching for a long time, I found 2 solutions as below:
The first solution is change the application theme from MaterialComponents to AppCompat in values/themes.xml file. then state drawable will work well.
to
<style name="Theme.MyApplication" parent="Theme.AppCompat.DayNight.DarkActionBar">
If you still want to use MaterialComponents theme then you can try the second solution.Use <android.widget.Button instead of <Button or <com.google.android.material.button.MaterialButton
<android.widget.Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#drawable/state_test"
android:text="Button" />
The second solution I found at Here
The main reason for this decision by the google design team to exclude the functionality android:background="#drawable/" from the initial release versions of the material library is to enable developers to build consistent and professional-looking designs for apps at a faster pace. This is because most developers like me are bad in making decisions related to design and colors of the app.
Also, I found this snippet from google tutorial while migrating to MDC.
Just by using android:backgroundTint
<style name="MyButtonStyle" parent="Widget.MaterialComponents.Button">
<item name="android:backgroundTint">#color/pink</item>
</style>
<com.google.android.material.button.MaterialButton
android:id="#+id/followButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/channel_header_item_margin"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toBottomOf="#id/titeChannelTV"
style="#style/MyButtonStyle"/>
using a simple
app:backgroundTint="#null"
with button attributes works perfectly.