Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Scale Animation - Reverse Issue

I managed to add a scale animation to my Image which makes it grow from it original size to a bigger size. However I need to add another copy of the animation code that makes it scale back to its' original size. I am trying to loop the animation while the boolean is true.

I played around the parameters a bit but I couldn't make it work. Here's my code so far:

class AnimateButton extends AsyncTask<Void, Void, Void> {

        @Override
        protected Void doInBackground(Void... params) {

            Boolean isGlowing = true; //Make it run forever
            while (isGlowing) {
                scal_grow = new ScaleAnimation(0, 1.2f, 0, 1.2f, Animation.RELATIVE_TO_SELF, (float) 0.5, Animation.RELATIVE_TO_SELF, (float) 0.5);
                scal_grow.setDuration(1500);
                scal_grow.setFillAfter(true);
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        btn_layer.setAnimation(scal_grow);
                    }
                });

                try {
                    Thread.sleep(1500);
                } catch (Exception e) { }

                     //Add a reverse animation such that it goes back to the original size

            }
        return null;
     }
}

What changes should I make guys?

like image 210
Dinuka Jay Avatar asked Nov 27 '15 23:11

Dinuka Jay


2 Answers

In android, no animation and no UI update can happen on any other thread except the UIThread (the main thread).
Remove the AsyncTask and try using ViewPropertyAnimator which is better than ScaleAnimation in matter of performance. Plus, it's just one line.

To scale :

btn_layer.animate().scaleX(1.2f).scaleY(1.2f).setDuration(1500).start();

to unscale :

btn_layer.animate().scaleX(0.8f).scaleY(0.8f).setDuration(1500).start();

UPDATE

PropertyValuesHolder scalex = PropertyValuesHolder.ofFloat(View.SCALE_X, 1.2f);
PropertyValuesHolder scaley = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.2f);
ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(btn_layer, scalex, scaley);
anim.setRepeatCount(ValueAnimator.INFINITE);
anim.setRepeatMode(ValueAnimator.REVERSE);
anim.setDuration(1500);
anim.start();
like image 136
Rami Jemli Avatar answered Sep 28 '22 04:09

Rami Jemli


I would definitely recommend not using the legacy android.view.animation animations and use Property Animations instead. The old view animations aren't great, and don't work on the view like you'd expect.

Using property animations, this pulsing animation is quite simple. You can define it in XML like this:

<animator xmlns:android="http://schemas.android.com/apk/res/android"
    android:duration="1500"
    android:valueFrom="1"
    android:valueTo="1.2"
    android:valueType="floatType"
    android:repeatCount="infinite"
    android:repeatMode="reverse"/>

When you apply this, the animation will repeat indefinitely by reversing.

In Java it would look like this:

    PropertyValuesHolder scalex = PropertyValuesHolder.ofFloat(View.SCALE_X, 1.2f);
    PropertyValuesHolder scaley = PropertyValuesHolder.ofFloat(View.SCALE_Y, 1.2f);
    ObjectAnimator anim = ObjectAnimator.ofPropertyValuesHolder(btn_layer, scalex, scaley);
    anim.setRepeatCount(ValueAnimator.INFINITE);
    anim.setRepeatMode(ValueAnimator.REVERSE);
    anim.setDuration(1500);
    anim.start();

This will give you a much more expected experience, and takes care of the threading and timing for you. When you want to stop the animation, you simply call s.cancel() and you're done.

like image 30
rharter Avatar answered Sep 28 '22 04:09

rharter