Material Button won't cast white elevation shadow on Android 11 - android

I have a Material Button (from Google's Material Components) which can cast black shadow normally. But when I change the shadow color, it won't appear at all. Here's the button's XML portion :
<com.google.android.material.button.MaterialButton
android:id="#+id/next"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="#dimen/margin_activity_horizontal"
android:enabled="false"
android:elevation="8dp"
android:layout_margin="16dp"
android:text="#string/setup_next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintTop_toBottomOf="#id/nickname_entry_wrapper"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
tools:enabled="true"
android:textSize="18sp"
android:textColor="#000000"
android:backgroundTint="#FFFFFF"
android:fontFamily="#font/poppins_semibold"
android:paddingVertical="12dp"
android:outlineAmbientShadowColor="#FFFFFFFF"
android:outlineSpotShadowColor="#FFFFFFFF"
android:outlineProvider="background"
android:translationZ="8dp"
/>
As you can see, outlineAmbientShadowColor and outlineSpotShadowColor are supposed to change the shadow color that results from elevation and Z translation, right ? I tried adding both elevation and Z translation at once but nothing works, the button still has 0 shadow.
The button is a child view of a Constraint Layout that has a black background. As you can see, I even tried using different values for outlineProvider such as bounds or paddedBounds, yet..nothing.
If anyone has experience with these outline attributes, I'd love to have this solved. The problem isn't specific to Android 11 only, I am just saying that I am using Android 11 for testing, since those outline attributes are only available on Android versions later than Oreo.

As Mike M. has mentioned in the comment, those attributes don't really change the color, they just add a little 'tint'.
If you wanna use material buttons with more features, you should take a look at this library :
Github Repo: Carbon by ZieIony
It should fulfill the required objective (casting white shadows) successfully and without issues on all Android APIs.

Related

New Material Library: Center icon, above the text inside button

I have this button and I want to center the icon inside it but it should also be above the text.
The thing is, there is an option to set gravity of icon, Which is app:iconGravity but it only has two options and none of them is center.
If there's no text, setting the option to textStart moves the icon to the center but I want icon to be center and also above the text.
Here's the current code:
<com.google.android.material.button.MaterialButton
android:id="#+id/payButton"
style="#style/Widget.MaterialComponents.Button.Icon"
android:layout_width="0dp"
android:layout_height="96dp"
android:layout_weight="1"
android:fontFamily="#font/montserrat_regular"
android:text="#string/pay"
android:textColor="?attr/colorPrimary"
app:backgroundTint="#android:color/white"
app:icon="#drawable/ic_pay_black_24dp"
app:iconGravity="textStart"
app:iconSize="32dp"
app:iconTint="#color/colorPrimary" />
It seems that they don't think it's a good idea/design but their designer agreed to add the functionality in a future version.
Here is a request/discussion around this topic on their repo:
https://github.com/material-components/material-components-android/issues/671
Right now, the only possibilities that I've found are to:
Use android:drawableTop instead of app:icon: which is poorly customizable
Create you own custom view or layout and include it where you need it
I've just submitted a PR to add this feature, as it seems that they agree it should support top gravity.
Update (2021-02-17)
It should now be available on Material 1.3.0 by using one of the following options: app:iconGravity="top" or app:iconGravity="textTop"
The MaterialButton view don't allow to do what you want. You will do it manualy with you own views.

Show error for unsupported custom attribute

I am working on an Android Library, which makes buttons of different shapes. The Button's XML looks like this:
<com.singh.daman.mybutton.ShapedButton
android:id="#+id/round"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:fill_color="#color/colorPrimaryDark"
app:button_type="round_rectangle"
app:stroke_color="#color/colorAccent"
app:stroke_width="12sp"
app:text="Round Rectangle"
app:text_size="16sp"
app:text_color="#ffff"
android:layout_gravity="center"
android:background="#null" />
In which attribute app:button_type="round_rectangle" have different values like rectangle, star, circle and round rectangle.
The type round_rectangle is supported by only Lollipop and Above android versions.
So, When the library user sets button_type to round_rectangle and the app minimum android version is less than Lollipop, I want to show an error that it is only supported by api 21 and above, How can I do that?
You need a custom lint rule. I've never done this, but there are writeups from Google on the topic.
http://tools.android.com/tips/lint-custom-rules

FloatingActionButton (FAB) with Android Design support library not elevating

This is my FAB button:
<android.support.design.widget.FloatingActionButton
android:id="#+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:layout_margin="16dp"
android:src="#drawable/c"
app:elevation="6dp"
app:backgroundTint="#fa1d1d" />
I'm using the Design support lib: compile 'com.android.support:design:23.1.1' and testing on Android 6.0.1
The main problem is that regardless of the value I set for elevation, it looks the same every time. Here's the screenshot. First button has elevation set to 6, then 12, then 24
Feels like I'm missing something really simple.
It looks correct to me, I believe that you're misinterpreting the meaning of the elevation. Elevation only changes the shadow that is drawn under the view. From the docs:
The elevation of a view (...) determines the visual appearance of its shadow
(http://developer.android.com/training/material/shadows-clipping.html)
If you inspect closely, you'll see that the last button, the shadow is bigger and more "spread out".

Android support design floating action button elevation not visible for colors other than white

I'm using compile 'com.android.support:design:23.1.1' and android.support.design.widget.FloatingActionButton to create a FAB.
When the background tint color is white the elevation (shadow) is very visible.
But for other colors the elevation not visible.
Here is my code:
<android.support.design.widget.FloatingActionButton
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/create_floating_button"
app:elevation="6dp"
app:borderWidth="0dp"
android:clickable="true"
app:backgroundTint="#color/colorAccent"
app:rippleColor="#color/colorAccentLight"
android:layout_margin="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
Beside this problem, even with white color, the button doesn't seem like the ones in google material design spec.
Check this for example (the shadow's direction is down):
What am I doing wrong?
Make sure you have a specific layout-v21 file where you replace app:elevation with android:elevation. After API 21 you need to do this to maintain a good compatibility.

Android 5.0 - ProgressBar cannot be displayed over a Button

I think the title is pretty explicit about my problem... So here is my layout :
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login" />
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"/>
</RelativeLayout>
On android SDKs < 21, no problem, the ProgressBar is correctly displayed over the Button and centered in the Button. But on Android 5.0, the ProgressBar is displayed behind the Button.
So you can see it's correctly positionned it when you activate the option "Show layout bounds" in Developer Options settings, but you can't see anything on the screen without that option.
Would anybody know how to fix this? I guess it's a matter of elevation recently introduced, but I really don't know how to take care of it.
For the record, I'm using the recently released Theme.AppCompat style from the support.v7.
EDIT:
I also tried to apply setElevation(0) and setTranslationY(0) to the Button programmatically but it didn't change anything. So I wonder if it has to deal with the elevation.
You can add the android:translationZ attribute to the ProgressBar:
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="50dp"
android:layout_height="50dp"
android:translationZ="2dp"
android:layout_centerInParent="true"/>
Same issue here, my simple "hack" was too wrap the Button into another FrameLayout.
This way I don't care about the api version and other elevation issue ;)
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" >
<FrameLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button
android:id="#+id/button_action"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Login" />
</FrameLayout>
<ProgressBar
android:id="#+id/progress_bar"
android:layout_width="50dp"
android:layout_height="50dp" />
</FrameLayout>
Same question being asked here, with a better explanation of the issue:
https://stackoverflow.com/a/27216368/235910
To quote #CommonsWare:
The problem appears Android 5.0's elevation property. Apparently,
the RelativeLayout Z-axis ordering is tied into elevation. If both
widgets have the same elevation, the RelativeLayout will determine
the Z-axis order -- you can see that if you were to switch your layout
to be both Button widgets, for example. However, if one widget
(Button) has an elevation, and another widget (ImageView) does
not, the elevation will take precedence.
You can remove the Button elevation via
android:stateListAnimator="#null" or by defining your own custom
animator. Or, you can add some elevation to your ImageView to
get it to be higher on the Z axis than is the Button.
It is better to set android:translationZ more than 2dp. Your view/widget will disappear when you press the button. I explained the reason here.
<!-- Elevation when button is pressed -->
<dimen name="button_elevation_material">1dp</dimen>
<!-- Z translation to apply when button is pressed -->
<dimen name="button_pressed_z_material">2dp</dimen>
Button have these two values and defined in the framework.
If you add 'androidx.core:core' to your build.gradle, you can use this code for API < 21:
ViewCompat.setTranslationZ(viewToElevate, 5);
By default, if you want to show a view on top of a Button, it should have an elevation of at least 2dp.
This is caused by the fact that the elevation of a button is governed by their stateListAnimator. So long as it has one, setting the elevation to the button itself doesn't do anything. The stateListAnimator of Widget.MaterialComponents.Button has a default elevation of #dimen/mtrl_btn_elevation (2dp), so that's the elevation you have to take into account.
Doing android:stateListAnimator="#null" will also work, but that will get rid of any shadow effects at the button.

Categories

Resources