I have ScaleAnimation which change size of some View from small to big and then back to small (with RepeatMode = Reverse). It is repeated infinitely.
Each time animation has been repeated, I need to do some operation. I use onAnimationRepeat callback which is called when Animation reaches smallest or biggest state. But how to resolve which one of them? In other words how to get current value of ScaleAnimation?
Animation animation = new ScaleAnimation(
1f, 5f,
1f, 5f,
Animation.RELATIVE_TO_SELF, 0.5f,
Animation.RELATIVE_TO_SELF, 0.5f);
animation.setRepeatCount(Animation.INFINITE);
animation.setRepeatMode(Animation.REVERSE);
animation.setAnimationListener(new AnimationListener() {
public void onAnimationRepeat(Animation arg0)
{
//I NEED TO FIND OUT HERE WHETHER THE VIEW IS IN BIG OR SMALL STATE
//I can use below function but it works only on API >= 29
someView.getAnimationMatrix();
}
//other methods
});
someView.StartAnimation(animation);
I found getAnimationMatrix() method, which returns matrix of current animation values, but it is only available from API 29 and I need to support also lower Android versions.
Related
I'm animating a view and I want to reset the view to the original position after animation ended.
This is what I have:
rl2 is a relativeLayout
rl2.animate().translationX(-60).translationY(117).setDuration(2000);
I tried setting this but its not working:
rl2.clearAnimation();
clearAnimation(); does not reset your animations, it just stops them and removes them from the animation queue. To undo your animations you need to actually undo them. So, for your code block you will need to call rl2.animate().translationX(0).translationY(0).setDuration(2000); to move the view back to its original position.
As #Chris Stillwell mentioned on his answer, But you can move View back to it's original position after translation animation by
rl2.animate().translationX(0).translationY(0);
I know this question was asked long time ago but someone may still look for answer.
I use the Animation class for this kind of thing; there is a setFillAfter method in this class, so you can set if you want the animation to apply its transformation after it ends.
Animation anim = new ScaleAnimation(
1f, 1f, // Start and end values for the X axis scaling
1f, 2f, // Start and end values for the Y axis scaling
Animation.RELATIVE_TO_SELF, 0f, // Pivot point of X scaling
Animation.RELATIVE_TO_SELF, 1f); // Pivot point of Y scaling
anim.setFillAfter(false); // no needed to keep the result of the animation
anim.setDuration(1000);
anim.setAnimationListener(new Animation.AnimationListener() {
#Override
public void onAnimationStart(Animation animation) {
}
#Override
public void onAnimationEnd(Animation animation) {
}
#Override
public void onAnimationRepeat(Animation animation) {
}
});
gangsterImage.startAnimation(anim);
If you're going to remove view don't use animation.removeAllListeners(), the function cannot continue that's why you will see some error. If you want to disappear a view, use View.GONE
in Kotlin like this:
animation.doOnEnd {
binding.mainLayout.visibility = View.GONE}
But by this way you couldn't remove any animation! So it' better rest them to the initial position.
binding.tvM2.animate().translationX(0f).translationY(0f).rotation(0f)
just use anim.setFillAfter(false); to reset automatically after animation ends.
Hope I am not duplicating a question here; I couldn't find one about multiple ViewPropertyAnimators. The goal is to have a view animate from y1 to y2 in 8 seconds. Fade in the first second, and then fade out on the last second.
Here is what I have Tried in my Activity's onCreate():
final View animatingView = findViewById(R.id.animateMe);
animatingView.post(new Runnable() {
#Override
public void run() {
//Translation
animatingView.setY(0);
animatingView.animate().translationY(800).setDuration(8000);
//Fading view in
animatingView.setAlpha(0f);
animatingView.animate().alpha(1f).setDuration(1000);
//Waiting 6 seconds and then fading the view back out
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
animatingView.animate().alpha(0f).setDuration(1000);
}
}, 6000);
}
});
However, the result is a translation from 0 to 800, and alpha from 0 to 1 all in one second. and then 6 seconds later the view fades out. It looks every time I call View.animate() it returns the same ViewPropertyAnimator. Is there a way I can have multiple of them? I was thinking about animating the view's alpha, nesting the view in a relative layout, and then animating the relative layouts translation. I would rather not go that route if I don't have to. Does anyone know of a better solution?
You can solve this by using ObjectAnimator instances directly, rather than using the .animate() abstraction.
ObjectAnimator translationY = ObjectAnimator.ofFloat(animatingView, "translationY", 0f, 800f);
translationY.setDuration(8000);
ObjectAnimator alpha1 = ObjectAnimator.ofFloat(animatingView, "alpha", 0f, 1f);
alpha1.setDuration(1000);
ObjectAnimator alpha2 = ObjectAnimator.ofFloat(animatingView, "alpha", 1f, 0f);
alpha2.setDuration(1000);
alpha2.setStartDelay(7000);
AnimatorSet set = new AnimatorSet();
set.playTogether(translationY, alpha1, alpha2);
set.start();
On button click I would like to make an image move either down or right. The issue I am running into is that the movement of the image only occurs once. In onClick() method I am just calling either one of my move methods. Here are the move methods.
private void moveLeftToRight() {
animation = new TranslateAnimation(0.0f, 200.0f, 0.0f, 0.0f);
animation.setDuration(1500); // animation duration
animation.setFillAfter(true);
iv1.startAnimation(animation); // start animation
}
private void moveUpToDown() {
animation = new TranslateAnimation(0.0f, 0.0f, 0.0f, 200.0f);
animation.setDuration(1500); // animation duration
animation.setFillAfter(true);
iv1.startAnimation(animation); // start animation
}
I can call either one of these one time for the first time. Thereafter the animation methods do not work. I am wondering if I need to reset or something. Any ideas? Thanks in advance.
When you pass your coordinates to TranslateAnimation those coordinates are relative to 0,0 and not the views coordinates.
To fix this we will get the views coordinates with view.bottom, view.left etc.
Then add the values you'd like to transform by to those values, pass those to TranslateAnimation, and your translation will work as expected.
I have three animations like scale, translate and scale. I play those animations in order. First two is working fine but last scale animation reset the position of view to original. If I remove last scale animation, it's working fine the view stay the new position after translate animation. Do you have any idea about this behavior?
AnimationSet animationSet = new AnimationSet(false);
animationSet.setFillAfter(true);
ScaleAnimation scaleAnimation1 = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
scaleAnimation1.setDuration(500);
scaleAnimation1.setFillAfter(true);
TranslateAnimation moveAnim = new TranslateAnimation(0, -x, 0, -y);
moveAnim.setDuration(1000);
moveAnim.setStartOffset(500);
moveAnim.setFillAfter(true);
ScaleAnimation scaleAnimation2 = new ScaleAnimation(1.0f, 0.0f, 1.0f, 0.0f);
scaleAnimation2.setDuration(500);
scaleAnimation2.setStartOffset(1000);
scaleAnimation2.setFillAfter(true);
scaleAnimation2.setFillBefore(true);
animationSet.addAnimation(scaleAnimation1);
animationSet.addAnimation(moveAnim);
animationSet.addAnimation(scaleAnimation2);
scaleAnimation2.setFillAfter(true); - If fillAfter is true, the transformation that this animation performed will persist when it is finished
scaleAnimation2.setFillBefore(true);- If fillBefore is true, this animation will apply its transformation before the start time of the animation.
These two properties cannot work simultaneously, and the one which set later is effective.
So, remove scaleAnimation2.setFillBefore(true); may solve your problem.
I am trying to perform 2 text animations in a row with my TextView under Android
first:
TextView target = (TextView)findViewById(R.id.textanimation);
target.setText(text1);
target.startAnimation(animationSet1);
animationSet1 is a set of alpha and translate animations:
Animation alpha = new AlphaAnimation(0.0f, 1.0f);
Animation a = new TranslateAnimation(
Animation.RELATIVE_TO_SELF, 0, Animation.RELATIVE_TO_SELF, 0,
Animation.RELATIVE_TO_SELF, -1.0f,
Animation.RELATIVE_TO_SELF, 0);
alpha.setDuration( 1000 );
a.setDuration( 1000 );
When onAnimationEnd happens in animationSet1 I immediately start another animation
TextView target = (TextView)findViewById(R.id.textanimation);
target.setText(text2);
target.startAnimation(animationSet1);
However in the 2nd animation I can see on a split of second a fully opaque text, however it should start with 0 alpha. How to avoid this situation? Will appresiate any answer.
P.S. Even if I have 2 separate textviews with the prepared text in both - same bug is seen.
If I put some delay between the animations both of them become smooth.
Sergey
I'm not sure how you are triggering the start of the 2nd animation following the termination of the 1st animation. I'm guessing you're checking to see if the animation on a view is null. This isn't the best or correct way to do it. Instead you should you an AnimationListener
Animation animation1 = new Animation();//Replace with your animation
animation1.setDuration(DURATION_1);
animation1.setAnimationListener(new AnimationListener() {
public void onAnimationStart(Animation arg0) {}
public void onAnimationRepeat(Animation arg0) {}
public void onAnimationEnd(Animation arg0) {
Animation animation2 = new Animation();
animation2.setDuration(DURATION_2);
view2.startAnimation(animation2);
}
});
view1.startAnimation(animation1);