16

I want to vibrate a view with scaleX and scaleY, and I am doing it with this code, but the problem is that sometimes the view is not correctly reset, and it shows with the scale applied...

I want that when the animation ends, the view must be seen with its original status always

this is the code:

                ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.9f);
                scaleX.setDuration(50);
                scaleX.setRepeatCount(5);
                scaleX.setRepeatMode(Animation.REVERSE);
                ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.9f);
                scaleY.setDuration(50);     
                scaleY.setRepeatCount(5);
                scaleY.setRepeatMode(Animation.REVERSE);
                set.play(scaleX).with(scaleY);
                set.start();

Thanks

Puja
  • 192
  • 9
NullPointerException
  • 36,107
  • 79
  • 222
  • 382

3 Answers3

18

For ValueAnimator and ObjectAnimator can be like this a try:

animator.addListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationEnd(Animator animation) {
        animation.removeListener(this);
        animation.setDuration(0);
        ((ValueAnimator) animation).reverse();
    }
});

UPDATE On Android 7 it doesn't work. Best way use the interpolator.

public class ReverseInterpolator implements Interpolator {

    private final Interpolator delegate;

    public ReverseInterpolator(Interpolator delegate){
        this.delegate = delegate;
    }

    public ReverseInterpolator(){
        this(new LinearInterpolator());
    }

    @Override
    public float getInterpolation(float input) {
        return 1 - delegate.getInterpolation(input);
    }
}

In your code

animator.addListener(new AnimatorListenerAdapter() {
        @Override
        public void onAnimationEnd(Animator animation) {
            animation.removeListener(this);
            animation.setDuration(0);
            animation.setInterpolator(new ReverseInterpolator());
            animation.start();
        }
});
princeparadoxes
  • 498
  • 3
  • 10
3

According to the docs(Property Animation):

The property animation system can animate Views on the screen by changing the actual properties in the View objects. In addition, Views also automatically call the invalidate() method to refresh the screen whenever its properties are changed.

so you can use AnimatorListener to listen the animation event, then just reset the view property you animate. let's say cancel event and scaleX property:

scaleAnimator.setListener(new AnimatorListenerAdapter() {
    @Override
    public void onAnimationCancel(Animator animation) {
        scaleView.setScaleX(0)
    }
});

Hope this can help a bit.

ggaier
  • 331
  • 2
  • 6
-4

You can add an AnimatorListener, to be notified when the animation ends:

scaleY.addListener(new AnimatorListener() {

            @Override
            public void onAnimationEnd(Animator animation) {
                // TODO Restore view

            }
            @Override
            public void onAnimationStart(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }



            @Override
            public void onAnimationCancel(Animator animation) {

            }
        });
Álvaro Pérez Soria
  • 1,443
  • 1
  • 13
  • 26
  • yes, i know, but... how can i restore the original status of the view? – NullPointerException Dec 23 '14 at 08:27
  • Have you tried clearing animation with yourView.clearAnimation()?? – Álvaro Pérez Soria Dec 23 '14 at 08:35
  • Ok, I see that you are using an ObjectAnimator. This is a Property animation. There is a good explanation here about the difference between Property Animation and View animation. http://stackoverflow.com/questions/11855570/reset-animation-effects-in-android. You should try to create a View animation, as it does not affect the original view – Álvaro Pérez Soria Dec 23 '14 at 08:48