How to play one animation with multiple views in android - android

I want to play one animation with multiple views in android.
This is the simplified example of code.
This code works incorrectly.
Every startAnimation() call, affects all previously animated views
Please tell me, why it doesn't works and how to make it properly.
public SomeClass() {
private int currentViewID = 0;
private View[] views = { view1, view2, view3, view4, view5 }
private Animation anim = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_out);
public SomeClass() {
this.anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
if (SomeClass.this.currentViewID != SomeClass.this.views.length) SomeClass.this.hideNextView();
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
});
this.hideNextView();
}
private void hideNextView() {
this.views[this.currentViewID++].startAnimation(this.anim);
}
}

If you don't want to deal with many Animations in your class (one for each View) you could do things locally:
private int currentViewID = 0;
private View[] views = { view1, view2, view3, view4, view5 }
public SomeClass() {
this.hideNextView();
}
private void hideNextView() {
final Animation anim = AnimationUtils.loadAnimation(this.getContext(), android.R.anim.fade_out);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationEnd(Animation animation) {
if (SomeClass.this.currentViewID != SomeClass.this.views.length) SomeClass.this.hideNextView();
}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationStart(Animation animation) {}
});
this.views[this.currentViewID++].startAnimation(anim);
}

Related

Imageview visibility affected before animation

I'm working with some animations in my project :
I have my own animated class :
public class Anim1Foto implements Animator.AnimatorListener {
private ImageView imagen1;
private ImageView imagen2;
public Anim1Foto (ImageView pimagen1,ImageView pimagen2){
this.imagen1 = pimagen1;
this.imagen2 = pimagen2;
}
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
AnimatorSet as = new AnimatorSet();
ObjectAnimator anim = ObjectAnimator.ofFloat(imagen1, "translationY", 0,200);
anim.setDuration(2500);
as.playSequentially(anim);
as.start();
imagen1.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}
What i want to do is to translate my Imageview and then make it disappear with "setVisibility(INVISIBLE)" but what i'm getting is that the imageview don't appear at all at the beginnig, after making some tests it lead me to the conclusion : the visibility is being affected before the animatorSet start's....I'm guessing wrong? if so what would be a correct way to do this?
Please try with this:-
public class Anim1Foto implements Animator.AnimatorListener {
private ImageView imagen1;
private ImageView imagen2;
public Anim1Foto (ImageView pimagen1,ImageView pimagen2){
this.imagen1 = pimagen1;
this.imagen2 = pimagen2;
}
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
AnimatorSet as = new AnimatorSet();
ObjectAnimator anim = ObjectAnimator.ofFloat(imagen1, "translationY", 0,200);
anim.setDuration(2500);
as.playSequentially(anim);
as.start();
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
imagen1.setVisibility(View.INVISIBLE);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
}

OnTouchListener on ImageView during animation, not fired/called sometimes

I have
Layout Game (Relative Layout)
ImageView (The Player)
ViewPropertyAnimator (The Animation)
My Code is:
final Vibrator vibe = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
final ImageView playerImageView = (ImageView) layoutInflater.inflate(R.layout.player, null);
playerImageView.setLayoutParams(new RelativeLayout.LayoutParams(playerSizeX, playerSizeY));
playerImageView.setImageDrawable(playerDrawable);
playerImageView.setX(playerVisualPositionX);
playerImageView.setY(playerVisualPositionY);
playerImageView.setOnTouchListener(new OnTouchListener() {
#Override
public boolean onTouch(View view, MotionEvent motionEvent) {
if (motionEvent.getAction() == MotionEvent.ACTION_DOWN) {
vibe.vibrate(100);
touchedPlayer();
}
return true;
}
});
layoutGame.addView(playerImageView);
ViewPropertyAnimator viewPropertyAnimator = playerImageView.animate();
viewPropertyAnimator.x(positionAnimateX); // The view will be animated such that it moves to positionAnimateX.
viewPropertyAnimator.y(positionAnimateY); // The view will be animated such that it moves to positionAnimateY.
viewPropertyAnimator.setDuration(animationTime);
viewPropertyAnimator.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
//super.onAnimationEnd(animation);
layoutGame.removeView(playerImageView);
if (!gameOver && !gamePaused) {
addNewPlayer();
}
}
#Override
public void onAnimationStart(Animator animation) {
//super.onAnimationStart(animation);
currentAnimation = animation;
}
});
Sometimes I touch on the Player but onClicListener on ImageView is not called/fired method touchedPlayer() during animation. Do you know what it can be?
Try using an ObjectAnimator instead to animate X and Y for your view, I never experienced such problems and I use it a lot for stuff similar to what you're doing here.
Try this and see if it works:
layoutGame.addView(playerImageView);
PropertyValuesHolder xHolder = PropertyValuesHolder.ofFloat("X", playerImageView.getX(), positionAnimateX); // The view will be animated such that it moves to positionAnimateX.
PropertyValuesHolder yHolder = PropertyValuesHolder.ofFloat("Y", playerImageView.getY(), positionAnimateY); // The view will be animated such that it moves to positionAnimateY.
ValueAnimator valueAnimator = ObjectAnimator.ofPropertyValuesHolder(playerImageView, xHolder, yHolder);
valueAnimator.setDuration(animationTime);
valueAnimator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
//super.onAnimationStart(animation);
currentAnimation = animation;
}
#Override
public void onAnimationEnd(Animator animation) {
//super.onAnimationEnd(animation);
layoutGame.removeView(playerImageView);
if (!gameOver && !gamePaused) {
addNewPlayer();
}
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
valueAnimator.start();

Animate Floating Views, which don't have a parent layout?

How can I make a e.g. Fade out animation for a floating view that don't has a parent layout. This code works fine for everything nested inside layouts. Is there an option to make this possible for parents which are displayed in a floating service?
Code:
protected void FadeAnimation(View animationview, boolean fadein)
{
if(fadein){
//Fade in Animation
Animation animationFadeIn = AnimationUtils.loadAnimation(this, R.anim.introfadein);
animationFadeIn.setFillAfter(true);
animationFadeIn.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
animationview.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
animationview.setAnimation(animationFadeIn);
} else {
//Fade out Animation
Animation animationFadeOut = AnimationUtils.loadAnimation(this, R.anim.introfadeout);
animationFadeOut.setFillAfter(true);
animationFadeOut.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
animationview.setVisibility(View.GONE);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
animationview.setAnimation(animationFadeOut);
}
}
Thanks for your help! :)

Api 21 Circular Reveal Animation not working

I can't get the circular reveal animation to work.
I think I checked the most obvious things:
It starts, width and height are > 0 and it is visible, no Exception..
I load some data from the internet and display it in the view(fab)
The animation should only play after the download finishes.
TmdbHelper helper = new TmdbHelper();
helper.getMovieById(id, "en", new TmdbHelper.ResultListener() {
#Override
public void onResultReceived(JSONObject result) {
// called when finished downloading
try {
String rating = result.getString("vote_average");
AnimationHelper.circularReveal(fab, 500, 0);
fab.setText(rating);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
AnimationHelper:
public static void circularReveal(final View view, final long duration, long startDelay) {
// get the center for the clipping circle
int cx = (view.getLeft() + view.getRight()) / 2;
int cy = (view.getTop() + view.getBottom()) / 2;
// get the final radius for the clipping circle
int finalRadius = Math.max(view.getWidth(), view.getHeight());
// create the animator for this view (the start radius is zero)
Animator anim =
ViewAnimationUtils.createCircularReveal(view, cx, cy, 0, finalRadius);
anim.setDuration(duration);
anim.setStartDelay(startDelay);
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
view.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {}
});
// make the view visible and start the animation
anim.start();
}
I use the circular reveal animation in other parts like this to make sure the view is attached, and it works:
headerContainer.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
headerContainer.getViewTreeObserver().removeOnGlobalLayoutListener(this);
AnimationHelper.circularReveal(headerContainer, 500, 200);
}
});
Perhaps you should erase this line inside your onResultRecieved():
fab.setVisibility(View.VISIBLE);
My assumption is that your circular reveal method is working just fine. It is because of you have made the FAB visible before the animation even begin, you can't see it in action.
As an addition, those lines you've shown which is working doesn't have fab.setVisibility(View.VISIBLE) called anywhere in it.
1st Approach:
Try Transition Listener.
getWindow().getSharedElementExitTransition().addListener(new Transition.TransitionListener() {
#Override
public void onTransitionStart(Transition transition) {
}
#Override
public void onTransitionEnd(Transition transition) {
}
#Override
public void onTransitionCancel(Transition transition) {
}
#Override
public void onTransitionPause(Transition transition) {
}
#Override
public void onTransitionResume(Transition transition) {
}
});
2nd Approach: Try setting start delay and listener to the reveal animation and when animation starts then set the view visible
if (Build.VERSION.SDK_INT >= 21) {
Animator anim = ViewAnimationUtils.createCircularReveal(viewRoot, cx, cy, 0, finalRadius);
anim.setStartDelay(300);
anim.setDuration(1000);
anim.setInterpolator(new DecelerateInterpolator());
anim.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
viewRoot.setVisibility(View.VISIBLE);
}
#Override
public void onAnimationEnd(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.start();
}
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
anim.start();

Synchronize animation on multiple views

I would like to make a simple animation. My logo is divided in 4 parts :
1|2
3|4
I would like to fadein-out each part, but only one after the other : 1 -> 2 -> 4 -> 3 -> 1...
I have no problem with this, but sometimes my animation is not synchronized and the 4 parts animate simultaneously :
final ImageView logo1 = (ImageView) v.findViewById(R.id.logo1);
logo1.clearAnimation();
final ImageView logo2 = (ImageView) v.findViewById(R.id.logo2);
logo2.clearAnimation();
final ImageView logo3 = (ImageView) v.findViewById(R.id.logo3);
logo3.clearAnimation();
final ImageView logo4 = (ImageView) v.findViewById(R.id.logo4);
logo4.clearAnimation();
final Animation anim1 = AnimationUtils.loadAnimation(c, R.anim.animlogo);
anim1.setFillAfter(true);
anim1.setStartOffset(0);
final Animation anim2 = AnimationUtils.loadAnimation(c, R.anim.animlogo);
anim2.setStartOffset(anim1.getDuration());
anim2.setFillAfter(true);
final Animation anim3 = AnimationUtils.loadAnimation(c, R.anim.animlogo);
anim3.setStartOffset(anim1.getDuration()+anim2.getDuration());
anim3.setFillAfter(true);
final Animation anim4 = AnimationUtils.loadAnimation(c, R.anim.animlogo);
anim4.setStartOffset(anim1.getDuration()+anim2.getDuration()+anim3.getDuration());
anim4.setFillAfter(true);
anim1.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
anim1.setStartOffset(anim2.getDuration()+anim4.getDuration()+anim3.getDuration());
logo1.startAnimation(anim1);
}
});
anim2.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
anim2.setStartOffset(anim1.getDuration()+anim4.getDuration()+anim3.getDuration());
logo2.startAnimation(anim2);
}
});
anim3.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
anim3.setStartOffset(anim2.getDuration()+anim4.getDuration()+anim1.getDuration());
logo4.startAnimation(anim3);
}
});
anim4.setAnimationListener(new AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {}
#Override
public void onAnimationRepeat(Animation animation) {}
#Override
public void onAnimationEnd(Animation animation) {
anim4.setStartOffset(anim2.getDuration()+anim1.getDuration()+anim3.getDuration());
logo3.startAnimation(anim4);
}
});
logo1.startAnimation(anim1);
logo2.startAnimation(anim2);
logo4.startAnimation(anim3);
logo3.startAnimation(anim4);
anim1.startNow();anim2.startNow();anim3.startNow();anim4.startNow();
Any idea ?
Start only anim1:
logo1.startAnimation(anim1);
and in anim1's AnimationListener's onAnimationEnd do:
logo2.startAnimation(anim2);
This way anim2 won't start before anim1 is finished.

Categories

Resources