Custom Button Animation in Android

2019-06-07 23:05发布

问题:

In my application, when a user presses a button in the menu, I would like the button to scale to a larger size, and then when the button is released, it needs to scale back to its original size. In xml, I have created the following animator:

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="together">

    <objectAnimator
        android:propertyName="scaleX"
        android:duration="100"
        android:valueFrom="1.0"
        android:valueTo="1.3"
        android:valueType="floatType"/>

    <objectAnimator
        android:propertyName="scaleY"
        android:duration="100"
        android:valueFrom="1.0"
        android:valueTo="1.3"
        android:valueType="floatType"/>

</set>

On the Android developer page, it says you can create a state list for a custom button, like so:

<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:drawable="@drawable/button_pressed"
          android:state_pressed="true" />
    <item android:drawable="@drawable/button_focused"
          android:state_focused="true" />
    <item android:drawable="@drawable/button_default" />
</selector>

I have the custom background, so my question is: is there any way to apply my animation to the drawable in a state list like this? Or would I have to apply the animation to each button in my Java code? My application has a lot of buttons, so setting the animation for each one individually in Java would get very long. If I do have to apply the animation in the Java code, the button's onclick method is only called when the button is released, how would I detect when the button is first pressed down?

回答1:

You can do something like this:

  1. Create a file button_state_list_anim.xml and put it into anim folder (if you haven't got it, create it in your res folder)
  2. Add these lines to the file:

    <selector xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:state_enabled="true"
        android:state_pressed="true">
        <set>
            <objectAnimator
                android:duration="100"
                android:propertyName="scaleX"
                android:valueTo="1.3"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="100"
                android:propertyName="scaleY"
                android:valueTo="1.3"
                android:valueType="floatType" />
        </set>
    </item>
    <!-- base state -->
    <item android:state_enabled="true">
        <set>
            <objectAnimator
                android:duration="100"
                android:propertyName="scaleX"
                android:startDelay="100"
                android:valueTo="1"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="100"
                android:propertyName="scaleY"
                android:startDelay="100"
                android:valueTo="1"
                android:valueType="floatType" />
        </set>
    </item>
    <item>
        <set>
            <objectAnimator
                android:duration="0"
                android:propertyName="scaleX"
                android:valueTo="1"
                android:valueType="floatType" />
            <objectAnimator
                android:duration="0"
                android:propertyName="scaleY"
                android:valueTo="1"
                android:valueType="floatType" />
        </set>
    </item>
    

  3. In layout files where you use the button, add android:stateListAnimator= "@anim/custom_button_state_list_anim_material", for example

    <Button android:id="@+id/animated_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:stateListAnimator="@anim/custom_button_state_list_anim_material" android:text="Animated button" />



回答2:

add onTouchListener:

 button.setOnTouchListener(new View.OnTouchListener()
 {
                @Override
                public boolean onTouch(View v, MotionEvent event) 
                {

                  if (event.getAction() == MotionEvent.ACTION_DOWN)
                   {
                      here the button is pressed down
                   }



                    return false;
                }
            });