0

enter image description here

I made a button with the desired design as shown in the picture.

But when I click the button, the click effect does not appear.

The cause lies in the stateListAnimator="@null" property.

Clearing this property has no elevation effect.

And also, if you don't apply the backgroundTint to white, the shaodw is not visible.

This is a must have property because I want an elevation effect on a button.

The second way I do it is to use OutLineButton.

This also creates a similar design i want, but applying only 1dp of elevation effect will apply excessive elevation effect.

I don't know why either.

What should I do?

Why is this happening?

<Button
    android:id="@+id/delete_set"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:backgroundTint="@color/white"
    android:drawableLeft="@drawable/ic_remove_routine"
    android:text="DELETE SET"
    android:textSize="12dp"
    android:textColor="@color/orgin_text_color"
    android:elevation="10dp"
    android:stateListAnimator="@null"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="1dp"
    android:layout_marginRight="1dp"
/>
<Button
    android:id="@+id/add_set"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:drawableLeft="@drawable/ic_add_routine"
    android:backgroundTint="@color/white"
    android:text="ADD SET"
    android:textSize="12dp"
    android:textColor="@color/orgin_text_color"
    android:elevation="10dp"
    android:stateListAnimator="@null"
    android:layout_marginTop="10dp"
    android:layout_marginLeft="1dp"
    android:layout_marginRight="1dp"
 />
ybybyb
  • 1,385
  • 1
  • 12
  • 33

1 Answers1

2

Actually, you're removing the default StateListAnimator, as the name suggests you're nulling the property responsible for animating the button based on the state, so the button is behaving as expected. Note that the elevation property in StateListAnimator override the property on the button itself.

To achieve what you want, instead of setting StateListAnimator to null, you should implement your custom one. For reference, you can view the default animator here.

To do so, you can define a dimen in dimens.xml like this:

<dimen name="my_button_elevation">10dp</dimen>

Then, create an xml resource in animator/ folder called for example my_button_animator.xml with the following content:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:state_pressed="true" android:state_enabled="true">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="100"
                            android:valueTo="4dp"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="@dimen/my_button_elevation"
                            android:valueType="floatType"/>
        </set>
    </item>
    <!-- base state -->
    <item android:state_enabled="true">
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="100"
                            android:valueTo="0"
                            android:startDelay="100"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="@dimen/my_button_elevation"
                            android:valueType="floatType" />
        </set>
    </item>
    <item>
        <set>
            <objectAnimator android:propertyName="translationZ"
                            android:duration="0"
                            android:valueTo="0"
                            android:valueType="floatType"/>
            <objectAnimator android:propertyName="elevation"
                            android:duration="0"
                            android:valueTo="0"
                            android:valueType="floatType"/>
        </set>
    </item>
</selector>

Finally, you can use the property as follows

<item name="android:stateListAnimator">@animator/my_button_animator</item>

And delete the elevation property from the buttons as it will be overriden by the animator.

MSDarwish
  • 79
  • 1
  • 7
  • Thanks for your answer. However, I get a Cannot resolve symbol error in `duration, valueTo,startDelay(@integer, @dimen)`. Does this mean I should define `button_pressed_animation_duration` and` button_pressed_z_material` in a folder called `@integer and a dimen`? – ybybyb Feb 24 '21 at 17:15
  • 1
    Oh, and when I just set the `rippleColor property`, the button click effect started coming out with the color I set. Is this normal? – ybybyb Feb 24 '21 at 17:15
  • 1
    For the error, I've updated the code snippet to replace the resource id with the default value, check it out. For the ripple, it is the visual feedback of touch in clickable views, so surely it is the expected behaviour. View documentation for more info: https://material.io/develop/ios/components/ripple – MSDarwish Feb 24 '21 at 18:53
  • Thanks. But I forgot to ask how much should the `startDelay` property be set? – ybybyb Feb 24 '21 at 20:21
  • 1
    It's 100ms. I've update the code snippet again. Sorry for forgetting about that. – MSDarwish Feb 24 '21 at 21:25
  • Strange that the default state list animator ELEVATES buttons while pressed? Wouldn't you expect them to be pressed down? – Flyview Jun 22 '23 at 21:25