2

According to documentation setStartTime should help with starting animation from particular step. What I mean is if I have animation android:duration = "2000" I want to make it start in java from particular time e.g from 1500 or whatever else. Once again it is not delay of animation start like setStartOffset but start from particular step of animation.

After digging a little bit more I have found that startAnimation is not affected by startTime and always begins from the 1st frame. On the other hand setAnimation should be used for setStartTime unfortunately I can not pass there my long value and can not pass it into currentAnimationTimeMillis.

updated code

in MainActivity ...
Animation introani;
TextView intro;

in onCreate..
    intro= (TextView) findViewById(R.id.intro);
    introani = AnimationUtils.loadAnimation(this, R.anim.introalpha);

    ViewTreeObserver vto = intro.getViewTreeObserver(); //@diegoveloper
    vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
        @Override
        public void onGlobalLayout() {
            introani.setStartTime(1500);
            intro.setAnimation(introani);
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                intro.getViewTreeObserver().removeOnGlobalLayoutListener(this);
            } else {
                intro.getViewTreeObserver().removeGlobalOnLayoutListener(this);
            }
        }
    });

It still has duration of 2000 but in that case animation never starts.

Any ideas how to run animation from particular step?

JayJayAbrams
  • 195
  • 1
  • 16

2 Answers2

0

Call setAnimation after your view finish the rendering:

     intro= (TextView) findViewById(R.id.intro);
introani = AnimationUtils.loadAnimation(this, R.anim.introalpha);
introani.setStartTime(1500);
ViewTreeObserver vto = intro.getViewTreeObserver(); //@diegoveloper
vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
    @Override
    public void onGlobalLayout() {
        intro.setAnimation(introani);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
            intro.getViewTreeObserver().removeOnGlobalLayoutListener(this);
        } else {
            intro.getViewTreeObserver().removeGlobalOnLayoutListener(this);
        }
    }
});

Try using setStartOffset instead setStartTime :

setStartOffset

diegoveloper
  • 93,875
  • 20
  • 236
  • 194
  • I tried that option but as mentioned in the question that line starts animation from 1st frame. Whilst I need animation to run from 1500 frame (or duration time) out of 2000 – JayJayAbrams Dec 17 '17 at 17:30
  • _ @diegoveloper `OnGlobalLayoutListener` = cannot resolve and `removeGlobalOnLayoutListener` = deprecated. Also "add after view finish the rendering" means to add your snippet after ` introani = AnimationUtils.loadAnimation(this, R.anim.introalpha);` ? – JayJayAbrams Dec 17 '17 at 17:41
  • _ @diegoveloper "this" cannot be applied to () and OnGlobalLayoutListener = cannot resolve, and where do I put that snippet? – JayJayAbrams Dec 17 '17 at 17:46
  • _ @diegoveloper `observer` = cannot resolve, and in `else` removeGlobalOnLayoutListener = deprecated. – JayJayAbrams Dec 17 '17 at 17:52
  • _ @diegoveloper yes, no more errors, but still when do I pass new timer? And where do I put your snippet? I added it in onCreate after `introani = AnimationUtils.loadAnimation(this, R.anim.introalpha);` and tried introani.setStartTime(1500); in `vto` and after. Does not work. – JayJayAbrams Dec 17 '17 at 18:01
  • _ @diegoveloper used it however problem with `setStartTime` and `setAnimation` are the same. `1.` animation does not start at 1500 `2.` animation does not start at all `3.` duration timer =2000 works – JayJayAbrams Dec 17 '17 at 18:11
  • check your introalpha file – diegoveloper Dec 17 '17 at 18:21
  • Try using setStartOffset instead setStartTime – diegoveloper Dec 17 '17 at 18:26
  • _ @diegoveloper thank you! Here is what I did. `introani.setStartOffset(1500);` before vto and ` intro.startAnimation(introani);`. In that case animation starts after 1500 from 1st frame but that was working w/o vto as well. – JayJayAbrams Dec 18 '17 at 02:06
  • _ @diegoveloper what exaclty should I check in _introalpha_ ? Apparently I am missing the point how `setStartTime` really works. According to documentation time passed to method should come from `currentAnimationTimeMillis()` but I can't find any way to update it. – JayJayAbrams Dec 18 '17 at 02:16
  • _ @diegoveloper I am sorry I can not since goal was not to delay start but to start from some time passed. – JayJayAbrams Dec 18 '17 at 02:17
0

SOLUTION

Use valueAnimator or objectAnimator documentation lnk instead of animation. Also to mention it was added in API level 26!!! (while same string in valueAnimator asks for v11 documentation so it could be done rather programaticaly).

Here is example

private static ObjectAnimator showScaleXObj(View view, long duration, long curPlayTime, float start, float stop) {
    ObjectAnimator showScaleXObj = ObjectAnimator.ofFloat(view, View.SCALE_X, start, stop);
    showScaleXObj.setDuration(duration);
    showScaleXObj.setCurrentPlayTime(curPlayTime);
    showScaleXObj.start();
    return showScaleXObj;
}

Even though adding multiple animations would look huge it is still a nice solution.

OLD ANSWER about animation

Apparently there is no easy way to implement this. Thanks to @diegoveleper for help unfortunately it might be impossible.

First of all that is tween animation. Here are instructions on implementation of setAnimation and setStartTime

    introani = AnimationUtils.loadAnimation(this, R.anim.introalpha);

    final long currAnimTime = AnimationUtils.currentAnimationTimeMillis();
    long startOffSet = 1500;
    introani.setStartTime(currAnimTime + startOffSet);
    intro.setAnimation(introani);

You must acquire .currentAnimationTimeMillis then use it in setStartTime with long value you want. In this case setAnimation works (!) and it starts animation with some delay from 1st frame.

To conclude setAnimation part. The setStartTime is literally time when animation starts

    final long currAnimTime = AnimationUtils.currentAnimationTimeMillis();
    long startOffSet = 1500;
    introani.setStartTime(currAnimTime + startOffSet);
    intro.setAnimation(introani);

and it works same as setStartOffset since last one is only a delay before start.

    long startOffSet = 1500;
    introani.setStartOffset(startOffSet);
    intro.setAnimation(introani);

More information. There is a way for start from particular step via AnimationDrawable solution and pause/play (just to read). Unfortunately it requires only frame animation d̶r̶a̶w̶a̶b̶l̶e̶ ̶f̶i̶l̶e̶s̶ ̶h̶e̶n̶c̶e̶ ̶i̶t̶ ̶i̶̶̶s̶̶̶ ̶̶̶p̶̶̶o̶̶̶s̶̶̶s̶̶̶b̶̶̶i̶̶̶b̶̶̶l̶̶̶e̶̶̶ ̶̶̶t̶̶̶o̶̶̶ ̶̶̶p̶̶̶l̶̶̶a̶̶̶y̶̶̶ ̶̶̶g̶̶̶i̶̶̶f̶̶̶ ̶̶̶I̶ ̶g̶u̶e̶s̶s̶ ̶b̶u̶t̶ ̶i̶m̶p̶o̶s̶s̶i̶b̶l̶e̶ ̶t̶o̶ ̶p̶l̶a̶y̶ ̶a̶n̶i̶m̶a̶t̶i̶o̶n̶.̶x̶m̶l̶.

JayJayAbrams
  • 195
  • 1
  • 16