Search code examples
androidobjectanimator

valueanimator.start is restaring the animation after valueanimator.cancel on API < 19


i know this is asked before i tried all the solution but i cannot arrive to fix it, i have objects that fall from the top of the screen to the bottom of the screen using translation in android library.

i want to the pause the animation and resume it:

PAUSE CODE fixed from the suggestion on one of the stack overflow posts:

private void pauseAnimation() {
        p = true;
        Pausearray = new MyClass[mAllImageViews.size()];
        int count = 0;
        for (ArrowView v : mAllImageViews) {
            ValueAnimator va = (ValueAnimator) v.getTag();
            if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                va.pause();
            } else {
                if (va != null) {
                    MyClass temp = new MyClass();
                    temp.tag = v.getTag().toString();
                    temp.playtime = va.getCurrentPlayTime();
                    Pausearray[count] = temp;
                    va.cancel();
                }
            }
            count ++;
        }
    }

the pause is working the annimation is stoping from moving and its staying in its position.

RESUME CODE suggested by one of the stack overflow posts:

   private void resumeAnimation() {
        p = false;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            for (ArrowView v : mAllImageViews) {
                try {
                    ValueAnimator va = (ValueAnimator) v.getTag();
                    va.resume();
                } catch (Exception ex) {

                }
            }
        } else {
            if(Pausearray!=null) {
                for (ArrowView v : mAllImageViews) {
                    ValueAnimator va = (ValueAnimator) v.getTag();
                    for (int i = 0; i < Pausearray.length; i++) {
                        if(v.getTag().toString().equalsIgnoreCase(Pausearray[i].tag)){
                            va.start();
                            va.setCurrentPlayTime(Pausearray[i].playtime);
                        }
                    }
                }
            }
        }
    }

the problem with the resume that it's starting from the top again i want it to continue where it was it's position on screen. Thank you!

Update:

i tried to get the arrow view position from screen and set it at resume, i'm still getting the same issue, views are restarting so the edited code is:

  private void resumeAnimation() {
        p = false;
        if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
            for (ArrowView v : mAllImageViews) {
                try {
                    ValueAnimator va = (ValueAnimator) v.getTag();
                    va.resume();
                } catch (Exception ex) {

                }
            }
        } else {
            if(Pausearray!=null) {
                for (ArrowView v : mAllImageViews) {
                    ValueAnimator va = (ValueAnimator) v.getTag();
                    for (int i = 0; i < Pausearray.length; i++) {
                        if(v.getTag().toString().equalsIgnoreCase(Pausearray[i].tag)){
                            Log.w("PAUSETEST","Setting Parameters "+Pausearray[i].playtime);
                            va.start();
                            va.setCurrentPlayTime(Pausearray[i].playtime);
                            v.setY(Pausearray[i].translationy); // i took the location via v.gettranslationY on pause
                        }
                    }
                }
            }
        }
    }

UPDATE: i heard while i was searching that valueanimator doesn't restart so i switched the valueanimator to object animator animator code:

 public void startAnimation(final ArrowView aniView) {
    aniView.setPivotX(aniView.getWidth());
    aniView.setPivotY(aniView.getHeight());

    long delay = new Random().nextInt(Constants.MAX_DELAY);// generate a random delay time before the animation starts to go down

    ObjectAnimator animator = ObjectAnimator.ofFloat(aniView,"translationY", mDisplaySize.bottom - (buttonsize) - (90 * mScale));
    if (aniView.getColor() == 0 && aniView.draw == false) {
        Constants.ANIM_DURATION = Constants.ANIM_DURATION_NORMAL;
    } else if (aniView.getColor() != 0 && aniView.draw == false) {
        Constants.ANIM_DURATION = Constants.ANIM_DURATION_COLOR;
    } else if (aniView.getColor() == 0 && aniView.draw == true) {
        Constants.ANIM_DURATION = Constants.ANIM_DURATION_COLOR;
    } else if (aniView.getColor() != 0 && aniView.draw == true) {
        Constants.ANIM_DURATION = Constants.ANIM_DURATION_COLORANDCALC;
    }
    animator.setDuration(Constants.ANIM_DURATION);// speed of the falldown
    animator.setInterpolator(new AccelerateInterpolator());
    animator.setStartDelay(delay);// start the animation after the delay.
//        animator.addUpdateListener(new AnimatorUpdateListener() {
//
//            //int angle = 50 + (int) (Math.random() * 101);
//            //int movex = new Random().nextInt(mDisplaySize.right);
//
//            @Override
//            public void onAnimationUpdate(ValueAnimator animation) {
//                float value = ((Float) (animation.getAnimatedValue())).floatValue();
//                //aniView.setRotation(angle*value);
//                //aniView.setTranslationX((movex-40)*value);
//                aniView.setTranslationY((mDisplaySize.bottom - (buttonsize)) * value - (90 * mScale));// set the translation to fall down and stop on the top of buttons
//            }
//        });
    aniView.setTag(animator);
    animator.start();
}

and i changed the code of the pause/resume to cast it into object animator and I'm still facing the same problem... on start is restarting the animation! please someone help! thanks!


Solution

  • After Playing around with valueanimator class i figured out a trick to make the animation stop, and resume its not an authentic way, but it solves the problem, i extended from value animator class and replaced the normal animator in my main class with the myvalueanimator class and here the play around in the value animator class:

    import android.animation.ValueAnimator;
    import android.util.Log;
    
    import java.util.Timer;
    
    /**
     * Created by win7 on 6/21/2017.
     */
    
    public class MyValueAnimator extends ValueAnimator {
        private float animatedValue = 0;
        private long currenttime;
        private long totaltime;
        private boolean onetime = true;
        private volatile boolean mPaused = false;
        private Timer t;
    
    public void pause() {
        animatedValue = (float) getAnimatedValue();
        mPaused = true;
    }
    
    //    @Override
    //    public void setValues(PropertyValuesHolder... values) {
    //        if (mPaused)
    //            return;
    //        super.setValues(values);
    @Override
    public Object getAnimatedValue() {
        if (mPaused) {
            if(onetime){
                currenttime = getCurrentPlayTime();
             //   totaltime = getStartDelay()+ (getDuration() * (getRepeatCount() + 1));
                totaltime = getDuration();
                setDuration(Long.parseLong("9999999999999999"));
                Log.w("PauseDur",Long.parseLong("9999999999999999")+"");
                onetime =false;
            }
            return animatedValue;
        }
        return super.getAnimatedValue();
    }
    
    public void resume() {
        mPaused = false;
        onetime=true;
        setCurrentPlayTime(currenttime);
        setDuration(totaltime);
    }
    
    public MyValueAnimator(float from, float to) {
        setFloatValues(from, to);
    }
    
    }