Reputation: 12943
This code switches the y-position
of two Views (mView1 and mView2) on Button click via ObjectAnimator
and AnimationSet
s. While the translate animation the alpha
value of both views will be reduced and growth again. This is just a setup to play around a bit. The alpha animation is defined in XML and the translate animation is done with code.
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android"
android:ordering="sequentially">
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="0.5"
android:valueType="floatType"/>
<objectAnimator
android:propertyName="alpha"
android:duration="500"
android:valueTo="1.0"
android:valueType="floatType"/>
</set>
@Override
public void onClick(View v) {
if (mView1 != null && mView2 != null) {
int top = mView2.getTop();
ObjectAnimator translateView1 = null;
ObjectAnimator translateView2 = null;
if (mView1.getTranslationY() == 0) {
translateView1 = ObjectAnimator.ofFloat(mView1, "translationY", top);
translateView2 = ObjectAnimator.ofFloat(mView2, "translationY", top*(-1));
} else {
translateView1 = ObjectAnimator.ofFloat(mView2, "translationY", 0);
translateView2 = ObjectAnimator.ofFloat(mView1, "translationY", 0);
}
translateView1.setDuration(1000L);
translateView2.setDuration(1000L);
AnimatorSet alpha1 = (AnimatorSet)AnimatorInflater.loadAnimator(mCtx, R.anim.switcher);
alpha1.setTarget(mView1);
AnimatorSet alpha2 = (AnimatorSet)AnimatorInflater.loadAnimator(mCtx, R.anim.switcher);
alpha2.setTarget(mView2);
AnimatorSet set = new AnimatorSet();
set.playTogether(translateView1, translateView2, alpha1, alpha2);
set.start();
}
}
Now, because this is working as expected, I wanna know how I can shorten the code?
Is it really necessary to have a seperate instance of an AnimatorSet
for every View
, which uses the animation from XML? Can I inflate the xml once and use it on different AnimatorSets / ObjectAnimators? Because I didn't found a setter which takes an Animator as an Argument.
Can I define multiple targets for one AnimationSet/ObjectAnimator? Or is the only way to define different ObjectAnimators for the Views and use them in a AnimationSet?
Upvotes: 1
Views: 832
Reputation: 3263
You will want to put the animation code inside the class that's animated ... like this :
public class FadingView extends View {
private ObjectAnimator fade, moveX, moveY;
private AnimatorSet moveSet;
public FadingView(Context context) {
super(context);
}
private void fade(int duration, float...values) {
if(fade==null) {
fade = ObjectAnimator.ofFloat(this, "alpha", values);
} else {
fade.setFloatValues(values);
}
fade.setDuration(duration);
fade.start();
}
private void move(int duration, int x, int y) {
if(moveX==null) {
moveX = ObjectAnimator.ofFloat(this, "translation_x", x);
} else {
moveX.setFloatValues(x);
}
if(moveY==null) {
moveY = ObjectAnimator.ofFloat(this, "translation_y", y);
} else {
moveY.setFloatValues(y);
}
if(moveSet == null) {
moveSet = new AnimatorSet();
moveSet.playTogether(moveX, moveY);
}
moveSet.setDuration(duration);
moveSet.start();
}
public void moveToUpperLeft(int duration) {
move(duration, 0,0);
}
public void show(int duration) {
fade(duration,1);
}
public void hide(int duration) {
fade(duration,0);
}
}
Just a basic example, but now you can call :
FadingView view = new FadingView(context);
view.hide(500);
view.moveToUpperLeft(500);
Of course you can customize and generalize this even more ...
Upvotes: 1