Animator onAnimationEnd cant change text - android

I'm translating a TextView 500dp to the right of the screen and then I use a listener to listen for the animation end where I want to change the text and then translate the TextView back to its initial space.
My code is :
ObjectAnimator animator = ObjectAnimator.ofFloat(rvDownCircle, "x", 500f);
animator.setStartDelay(500);
animator.setDuration(1500);
animator.start();
animator.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
rvDownCircle.setText("New Label");
ObjectAnimator animator = ObjectAnimator.ofFloat(rvDownCircle, "x", 0);
animator.setDuration(1000);
animator.start();
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
The TextView is named rvDownCircle and as you can see when I'm on AnimationEnd I change the text to a new text - but what it happens is that text stays the same.
My question is : what am i doing wrong here and what should i change so when i reach the end of the animation setText will take effect.

Related

ValueAnimator working with Button but not with LinearLayout

The following code is working when the supplied view is a Button but when it's a LinearLayout nothing happens (Background color doesn't change).
If I manually set the color on the LinearLayout without the ValueAnimator it works. I also tried using a ObjectAnimator but the result looked terrible.
An example call:
playBlinkAnimation(view, activity.getResources().getColor(R.color.transparent), activity.getResources().getColor(R.color.colorRed), 5000);
view.getBackground().setColorFilter(activity.getResources().getColor(R.color.colorRed), PorterDuff.Mode.DARKEN);
private void playBlinkAnimation(final View view, int colorFrom, int colorTo, int duration) {
ValueAnimator colorAnimation = new ValueAnimator();
colorAnimation.setIntValues(colorFrom, colorTo);
colorAnimation.setEvaluator(new ArgbEvaluator());
colorAnimation.setDuration(duration);
colorAnimation.setRepeatCount(ValueAnimator.INFINITE);
colorAnimation.setRepeatMode(ValueAnimator.REVERSE);
colorAnimation.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
#Override
public void onAnimationUpdate(ValueAnimator animator) {
view.getBackground().setColorFilter((int) animator.getAnimatedValue(), PorterDuff.Mode.DARKEN);
}
});
colorAnimation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationEnd(Animator animation) {
view.getBackground().setColorFilter(null);
}
#Override
public void onAnimationCancel(Animator animation) {
view.getBackground().setColorFilter(null);
view.setAlpha(1);
view.getBackground().setColorFilter(null);
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
colorAnimation.start();
}
You can try using AnimatorSet and it's playTogether function. It takes an array of Animators, and it's designed to run multiple animations together, but it should work with only one animation as well.
Hope that helps you!
Since you seem to want your layout to transition from transparent background to opaque red, you should animate the layout's alpha parameter
ObjectAnimator animator = ObjectAnimator.ofInt(view, "alpha", 0, 1);
animator.setDuration(5000);
animator.setInterpolator(new LinearInterpolator());
animator.start();

Animate every EditText one by one

I have a login screen with some EditText TextView and Button what I want to do is when the login screen is created I want to animate the first EditText from top to bottom then the second EditText from top to bottom after the first EditText is animated, so it should look like all the views are animating from top to bottom one by one.
This is kinda ugly but it'll work.
float pixels = 20f;
view1.animate().translationY(pixels).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationEnd(Animator animation) {
view2.animate().translationY(pixels).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationEnd(Animator animation) {
view3.animate().translationY(pixels);
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
Step 1
Animation scaleDown = AnimationUtils.loadAnimation(youContext, R.anim.scale_down);
ImagView v = findViewById(R.id.your_view);
v.startAnimation(scaleDown);//Start Animation
Step 2 Set Animation listener
Step 3 On Animation end start animated next view like above
so on.....

How to get Animation from View

I've set an Animation on ProgressBar in click event in Adapter
ObjectAnimator animation = ObjectAnimator.ofInt(holder.progressbar, "progress", 0, 100);
animation.setDuration(PROGRESS_TIME);
animation.setInterpolator(new DecelerateInterpolator());
animation.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animator) {
Toast.makeText(context,"HELL_Start",Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationEnd(Animator animator) {
//do something when the countdown is complete
Toast.makeText(context,"HELL_OFF_END",Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationCancel(Animator animator) {
Toast.makeText(context,"HELL_OFF_Cancel",Toast.LENGTH_SHORT).show();
}
#Override
public void onAnimationRepeat(Animator animator) { }
});
animation.start();
I'm trying to get Animation (when list item values get changed) from the ProgressBar by using
AlphaAnimation animation = (AlphaAnimation)mProgressBar.getAnimation();
but it is returning null
You can set the animator object as the associated view's tag.
holder.progressbar.setTag(animation);
Than retrieve it later:
ObjectAnimator animator = (ObjectAnimator) holder.progressBar.getTag();
// Do something with animator

How to reset ObjectAnimator to it's initial status?

I want to vibrate a view with scaleX and scaleY, and I am doing it with this code, but the problem is that sometimes the view is not correctly reset, and it shows with the scale applied...
I want that when the animation ends, the view must be seen with its original status always
this is the code:
ObjectAnimator scaleX = ObjectAnimator.ofFloat(view, "scaleX", 1f, 0.9f);
scaleX.setDuration(50);
scaleX.setRepeatCount(5);
scaleX.setRepeatMode(Animation.REVERSE);
ObjectAnimator scaleY = ObjectAnimator.ofFloat(view, "scaleY", 1f, 0.9f);
scaleY.setDuration(50);
scaleY.setRepeatCount(5);
scaleY.setRepeatMode(Animation.REVERSE);
set.play(scaleX).with(scaleY);
set.start();
Thanks
For ValueAnimator and ObjectAnimator can be like this a try:
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
animation.removeListener(this);
animation.setDuration(0);
((ValueAnimator) animation).reverse();
}
});
UPDATE
On Android 7 it doesn't work.
Best way use the interpolator.
public class ReverseInterpolator implements Interpolator {
private final Interpolator delegate;
public ReverseInterpolator(Interpolator delegate){
this.delegate = delegate;
}
public ReverseInterpolator(){
this(new LinearInterpolator());
}
#Override
public float getInterpolation(float input) {
return 1 - delegate.getInterpolation(input);
}
}
In your code
animator.addListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationEnd(Animator animation) {
animation.removeListener(this);
animation.setDuration(0);
animation.setInterpolator(new ReverseInterpolator());
animation.start();
}
});
According to the docs(Property Animation):
The property animation system can animate Views on the screen by changing the actual properties in the View objects. In addition, Views also automatically call the invalidate() method to refresh the screen whenever its properties are changed.
so you can use AnimatorListener to listen the animation event, then just reset the view property you animate. let's say cancel event and scaleX property:
scaleAnimator.setListener(new AnimatorListenerAdapter() {
#Override
public void onAnimationCancel(Animator animation) {
scaleView.setScaleX(0)
}
});
Hope this can help a bit.
You can add an AnimatorListener, to be notified when the animation ends:
scaleY.addListener(new AnimatorListener() {
#Override
public void onAnimationEnd(Animator animation) {
// TODO Restore view
}
#Override
public void onAnimationStart(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
#Override
public void onAnimationCancel(Animator animation) {
}
});

Could not change view size by ViewPropertyAnimator?

I want to implement zoom feature on an ImageButton by Property Animation. For example, when I click the button, it will zoom out. And when I click it again, it will zoom in.
Here is part of my code:
OnClickListener clickPlayButtonHandler = new OnClickListener() {
#Override
public void onClick(View v) {
final ImageButton clickedButton = (ImageButton) v;
if((Boolean) v.getTag()) {
// zoom out
clickedButton.animate().setInterpolator(new AnticipateInterpolator()).setDuration(500).scaleXBy(-0.4f).scaleYBy(-0.4f).setListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
clickedButton.setImageResource(R.drawable.bg_pause);
System.out.println(clickedButton.getWidth()); // output the width of the button for checking
}
#Override
public void onAnimationEnd(Animator animation) {
clickedButton.setTag(false);
int d = clickedButton.getWidth();
System.out.println(clickedButton.getWidth());// output the width of the button for checking
}
#Override
public void onAnimationCancel(Animator animation) {}
#Override
public void onAnimationRepeat(Animator animation) { }
});
} else {
// process zoom in
}
}
};
I printed the width of the button before the animation start and the animation finished. However, I found they were the same. I thought when the zoom out animation finished the button width should be small than before. But it didn't.
Could not change view size by ViewPropertyAnimator?
There won't be changes in clickedButton.getWidth(), because the width of a view is not affected by scaling. You can think of getWidth() as a way to get unscaled width of a view. To change the width of a View requires a new measure/layout pass.
ViewPropertyAnimator doesn't change View's width/height or anything that could potentially trigger another layout pass. This is simply because layout passes are expensive and therefore could cause frame skipping, which is the last thing we want see during an Animation.
If you need to get scaled width of the button, you can do getScaleX() * clickedButton.getWidth()
Try the ObjectAnimator:
ObjectAnimator xAnimator =
ObjectAnimator.ofFloat(clickedButton, "scaleX", 1.0f, -0.4f);
ObjectAnimator yAnimator =
ObjectAnimator.ofFloat(clickedButton, "scaleY", 1.0f, -0.4f);
AnimatorSet animatorSet = new AnimatorSet();
animatorSet.setDuration(500);
animatorSet.playTogether(xAnimator, yAnimator);
animatorSet.setInterpolator(new AnticipateInterpolator());
animatorSet.addListener(new Animator.AnimatorListener() {
#Override
public void onAnimationStart(Animator animation) {
clickedButton.setImageResource(R.drawable.bg_pause);
System.out.println(clickedButton.getWidth());
}
#Override
public void onAnimationEnd(Animator animation) {
clickedButton.setTag(false);
int d = clickedButton.getWidth();
System.out.println(clickedButton.getWidth());
}
#Override
public void onAnimationCancel(Animator animation) {
}
#Override
public void onAnimationRepeat(Animator animation) {
}
});
animatorSet.start();

Categories

Resources