Change multiple properties with single ObjectAnimator?
Asked Answered
T

5

32

I have a pretty complex animation I need to code and I'm using a bunch of ObjectAnimators like the following:

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, TRANSLATION_X, value).setDuration(BASE_DURATION * 2);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view, TRANSLATION_Y, value).setDuration(BASE_DURATION * 2);

Is it possible to group the X and Y translations into the same ObjectAnimator rather than creating a bunch of them then adding them all into an AnimatorSet?

Thanks!

Turro answered 5/2, 2015 at 19:25 Comment(18)
instead of TRANSLATION_X / TRANSLATION_Y try your own property, let it be "myProperty" and see what happensYah
I can't do that. TRANSLATION_Y is just a constant. It's actually "translationY" which is the property used to translate along the Y axis. I can't create one, at least I don't think I can!Turro
ok try something like: ObjectAnimator.ofFloat(this, "myProperty", value)Yah
I'm confused. What is "myProperty" ???Turro
this is an animated property: when you start that Animator the framework will call this.setMyProperty(float) method several times where you can animate other properties as you wantYah
Correct. It must be a pre-defined property of the view. How would I merge two properties using this proposed method??]Turro
just cal view.setTranslationX(float)/view.setTranslationY(float)/whatever in setMyProperty methodYah
Thank you for your efforts but unfortunately this method won't help with what I'm aiming to do.Turro
yes it will help, just create a public void setMyProperty(float param) and call whatever you want inside itYah
That is not what I'm trying to do :)Turro
you want to change view's x and y position, right? so call view.setTranslationX(x); view.setTransletionY(y) inside setMyProperty()Yah
No. I want to group two properties into one ObjectAnimator.Turro
thats exactly what i'm saying! in your Activity just try: ObjectAnimator.ofFloat(this, "myProperty", start, end)Yah
You're a very stubborn guy, I have to say. Thanks for your help.Turro
stubborn? i made it several times, so i know what i'm saying... but if you insist, well, i cannot force you...Yah
Clearly you're trying to force me lolTurro
What @Yah suggests is the only way to go about this since ObjectAnimator can not handle more than one property. However, I don't really see the problem with not grouping them. If you don't need to add them to the AnimatorSet, see my answer below.Sedulous
That's all I really wanted to know. Whether or not ObjectAnimator can handle more than one property at a time. I guess it can't! Thanks :)Turro
Q
76
PropertyValuesHolder pvhX = PropertyValuesHolder.ofFloat(TRANSLATION_X, value);
PropertyValuesHolder pvhY = PropertyValuesHolder.ofFloat(TRANSLATION_Y, value);
ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(view, pvhX, pvhY);
animator.setDuration(BASE_DURATION * 2);
animator.start();

http://developer.android.com/guide/topics/graphics/prop-animation.html#views One ObjectAnimator

Quant answered 14/4, 2015 at 2:47 Comment(3)
@TheHungryAndroider, you should've accepted the answer ;)Cordelier
@TheHungryAndroider, What? It does exactly what you were asking for. It groups several of ObjectAnimators into a single one, that lets you animate multiple Properties.Cordelier
@blipinsk Fair enough :) Cheers!Turro
C
25

I think you should be using an AnimationSet. It practically does what you want and is the nice way of doing it because when I think of PropertyValuesHolder I don't think of Keyframes.

So yeah:

ObjectAnimator objectAnimator1 = ObjectAnimator.ofFloat(view, TRANSLATION_X, value);
ObjectAnimator objectAnimator2 = ObjectAnimator.ofFloat(view, TRANSLATION_Y, value);

AnimatorSet animatorSet = new AnimatorSet();
animatorSet.playTogether(objectAnimator1, objectAnimator2);
animatorSet.setDuration(BASE_DURATION * 2);

animatorSet.start();

You can add as many ObjectAnimators as you want.

Cordi answered 18/9, 2016 at 8:55 Comment(0)
S
5

If you are animating a view (like your example suggests), you could use a ViewPropertyAnimator:

view.animate().translationX(value_x).translationY(value_y).setDuration(duration).start();
Sedulous answered 5/2, 2015 at 19:33 Comment(3)
Would I be able to add a ViewPropertyAnimator into a set? Something similar to an AnimatorSet?Turro
I thought you were trying to avoid creating a AnimatorSet. No you wouldn't be able to add it to an AnimatorSet. What are you trying to achieve?Sedulous
Not entirely, no. So my AnimatorSet is used to move a bunch of different objects around, but I'd like to group each object's animations (X/Y translations, scales, etc) into a single objectTurro
V
5

An alternative approach I've used to add multiple properties to an object's animation is to use a mix of code and XML to define the animation. This is based on this documentation

For example, in XML I can setup AnimatorSets and ObjectAnimators for a single object with static values, and define a sequential sequence of changes (res/animator/moveout.xml)

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
    android:ordering="sequentially">
    <set>
        <objectAnimator
            android:propertyName="scaleX"
            android:duration="2000"
            android:valueTo="0.8"
            android:interpolator="@android:anim/decelerate_interpolator"/>
        <objectAnimator
            android:propertyName="scaleY"
            android:duration="2000"
            android:valueTo="0.8"
            android:interpolator="@android:anim/decelerate_interpolator"/>
        <objectAnimator
            android:propertyName="alpha"
            android:duration="2000"
            android:valueTo="0"
            android:interpolator="@android:anim/decelerate_interpolator"/>
    </set>
    <set>
        <objectAnimator
            android:propertyName="scaleX"
            android:duration="2000"
            android:valueTo="1.2"
            android:interpolator="@android:anim/accelerate_interpolator"/>
        <objectAnimator
            android:propertyName="scaleY"
            android:duration="2000"
            android:valueTo="1.2"
            android:interpolator="@android:anim/accelerate_interpolator"/>
        <objectAnimator
            android:propertyName="alpha"
            android:duration="2000"
            android:valueTo="1"
            android:interpolator="@android:anim/accelerate_interpolator"/>
    </set>
</set>

Then I can load these AnimatorSets/ObjectAnimators at runtime and modify their values with dynamically generated values:

    AnimatorSet firstSet = (AnimatorSet) AnimatorInflater.loadAnimator(this,
            R.animator.moveout);

    AnimatorSet secondSet = firstSet.clone();
    firstSet.setTarget(button);
    secondSet.setTarget(anotherButton);

    // Choreograph the animations
    // Change the duration of all child elements in the set
    firstSet.setDuration(1000);
    secondSet.setDuration(200);

    // Set start delay so second set plays after the first set
    secondSet.setStartDelay(2000);
    AnimatorSet anim = new AnimatorSet();
    anim.playTogether(firstSet,secondSet);
    anim.start();
Venetis answered 3/3, 2017 at 13:38 Comment(1)
how can we share the same interpolator, duration between multiple ObjectAnimators?Arsenide
T
3

Animating view could be done even easier:

v.animate().x(valueX).y(valueY).setDuration(500).start();

(In this snippet ViewPropertyAnimator has been used).

Their answered 27/6, 2015 at 22:20 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.