Finish setting Android ObjectAnimator after option?

In my Android app, I am using ObjectAnimator to transform an image this way:

ObjectAnimator transitionX = ObjectAnimator.ofFloat(v, "TranslationY", 190);

      

Is there a fillAfter option that will reset the view position to a new position after the animation finishes?

+3


source to share


4 answers


No, there is no choice for that. However, you can achieve the same effect using a listener where you can manually change it to its original position in onAnimationEnd (). Here's an example of scaling an image:



scaleDown.addListener(new Animator.AnimatorListener() {
                        @Override
                        public void onAnimationStart(Animator animation) {

                        }

                        @Override
                        public void onAnimationEnd(Animator animation) {
                            //Initial property values
                            tempIV.setScaleX(1f);
                            tempIV.setScaleY(1f);
                            tempIV.setAlpha(1f);
                        }

                        @Override
                        public void onAnimationCancel(Animator animation) {

                        }

                        @Override
                        public void onAnimationRepeat(Animator animation) {

                        }
                    });

      

+2


source


No, I would use the property animation system, assuming v is a view:



v.animate().translationY(190).withEndAction(new Runnable() {
        @Override
        public void run() {
           v.setTranslationY(v.getTranslationY()-190);
        }
    }).start();

      

+1


source


I think the correct way to handle this is to use an AnimationSet to combine two animations, one for translation and one for translation back.

Something like that

ObjectAnimator translateTo190= ObjectAnimator.ofFloat(v, "TranslationY", 190);
ObjectAnimator translateBack = ObjectAnimator.ofFloat(v, "TranslationY", 0);

AnimatorSet translate= new AnimatorSet();
translate.play(translateTo190).before(translateBack);
translate.start();

      

0


source


I had this problem when you were writing a card that played an animation where cards are quickly dealt from the central "deck". After a lot of trial and error, the way I worked was using the ObjectAnimator as follows.

I add one "deck" to the animation source and then a second card, which I actually animate. I use the following deal_from_drawpile.xml file to animate the map in two parts: the first part returns the map to the origin, and the second part scales and rotates the map as it "goes":

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
 android:interpolator="@android:anim/accelerate_interpolator"
 android:ordering="sequentially">
<set android:interpolator="@android:anim/accelerate_interpolator"
     android:ordering="together">
    <objectAnimator
        android:propertyName="translationX"
        android:duration="10"
        android:valueFrom="0.0f"
        android:valueTo="0.0f"/>
    <objectAnimator
        android:propertyName="translationY"
        android:duration="10"
        android:valueFrom="0.0f"
        android:valueTo="0.0f"/>
    <objectAnimator
        android:propertyName="scaleX"
        android:duration="10"
        android:valueFrom="0.75f"
        android:valueTo="0.75f"/>
    <objectAnimator
        android:propertyName="scaleY"
        android:duration="10"
        android:valueFrom="0.75f"
        android:valueTo="0.75f"/>
</set>
<set android:ordering="together">
    <objectAnimator
        android:propertyName="rotation"
        android:duration="300"
        android:valueFrom="0.0f"
        android:valueTo="360.0f"/>
    <objectAnimator
        android:propertyName="scaleX"
        android:duration="300"
        android:valueFrom="0.75f"
        android:valueTo="0.5f"/>
    <objectAnimator
        android:propertyName="scaleY"
        android:duration="300"
        android:valueFrom="0.75f"
        android:valueTo="0.5f"/>
</set>

      

Then in the code, I add the actual translation, which depends on how many hands are in the rough semicircle. The complete animation sequence is then added to the AnimatorSet and fired at the end. Code snippet;

        fullScreenContent.addView(dealtCardView);
    for (int iCard=0; iCard<numCards; iCard++) {
        for (int iPlayer = 0; iPlayer < numPlayers; iPlayer++) {
            dealtCardAnimator = dealtCardAnimator.clone();
            dealtCardAnimator.setTarget(dealtCardView);
            //offsets where the cards are dealt according to player
            ObjectAnimator playerOffsetXAnimator = ObjectAnimator.ofFloat(dealtCardView, "TranslationX", mGame.getPlayer(iPlayer).getPlayerLayout().getTranslationX());
            ObjectAnimator playerOffsetYAnimator = ObjectAnimator.ofFloat(dealtCardView, "TranslationY", mGame.getPlayer(iPlayer).getPlayerLayout().getTranslationY());
            if (lastDealtCardAnimator == null) dealSet.play(dealtCardAnimator).with(playerOffsetXAnimator).with(playerOffsetYAnimator);
            else dealSet.play(dealtCardAnimator).with(playerOffsetXAnimator).with(playerOffsetYAnimator).after(lastDealtCardAnimator);
            //The card is returned to the home point with the first portion of deal_from_drawpile

            lastDealtCardAnimator = dealtCardAnimator;
        }//end for iPlayer
    }//end for numCards
    dealSet.start();

      

Now I can tinker with the duration of each step in XML to get the effect I want. Note that you must insert duration into each element, not into the set section (where it is ignored and some arbitrary default is used instead).

0


source







All Articles