Reputation: 2166
I'm creating a ringing bell animation (an imageview rotated by 10 degrees and then -10). I'm setting two RotateAnimations and AnimationListeners, in both's onAnimationEnd I start the other animation on the ImageView. Here's how:
onCreate:
final RotateAnimation rotateAnimationLeft = new RotateAnimation(-10, 10, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
final RotateAnimation rotateAnimationRight = new RotateAnimation(10, -10, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimationLeft.setDuration(150);
rotateAnimationRight.setDuration(150);
rotateAnimationLeft.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
ivBell.startAnimation(rotateAnimationRight);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
rotateAnimationRight.setAnimationListener(new Animation.AnimationListener() {
@Override
public void onAnimationStart(Animation animation) {
}
@Override
public void onAnimationEnd(Animation animation) {
ivBell.startAnimation(rotateAnimationLeft);
}
@Override
public void onAnimationRepeat(Animation animation) {
}
});
ivBell.startAnimation(rotateAnimationRight);
I set up an onTouchListener in which I want to stop the animation.
ivBell.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
final int X = (int) event.getRawX();
switch (event.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
ivBell.clearAnimation();
break;
}
}
}
It doesn't work. What does it need to stop?
(or if this is a wrong approach, I'd appreciate some recommendations how I should ring that bell :) Thanks!)
Upvotes: 0
Views: 34
Reputation: 4070
The issue here is that whilst you're clearing the animation that's currently running, the animation end triggers the next animation (starting a new cycle). You need to remove the animation listener (set it to null) and then clear the animation,
if(ivBell.getAnimation() != null) {
ivBell.getAnimation().setAnimationListener(null);
ivBell.clearAnimation();
}
But in this case, you'd need to store the listener in a separate variable (incase you want to use it again). Maybe a much simpler alternative would be to just use a boolean flag that can be used to determine whether the 'subsequent' animations should be started in the animation listeners.
public class Main2Activity extends AppCompatActivity {
boolean shouldAnimateFlag = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
final ImageView ivBell = findViewById(R.id.ivBell);
final RotateAnimation rotateAnimationLeft = new RotateAnimation(-10, 10, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
final RotateAnimation rotateAnimationRight = new RotateAnimation(10, -10, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
rotateAnimationLeft.setDuration(150);
rotateAnimationRight.setDuration(150);
rotateAnimationLeft.setAnimationListener(new Animation.AnimationListener() {
@Override public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
if(shouldAnimateFlag) {
ivBell.startAnimation(rotateAnimationRight);
}
}
@Override public void onAnimationRepeat(Animation animation) { }
});
rotateAnimationRight.setAnimationListener(new Animation.AnimationListener() {
@Override public void onAnimationStart(Animation animation) { }
@Override
public void onAnimationEnd(Animation animation) {
if (shouldAnimateFlag) {
ivBell.startAnimation(rotateAnimationLeft);
}
}
@Override public void onAnimationRepeat(Animation animation) { }
});
ivBell.startAnimation(rotateAnimationRight);
ivBell.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//The following line will just stop the animation
// shouldAnimateFlag = false;
//You can start/stop using the following lines
if(shouldAnimateFlag) {
shouldAnimateFlag = false;
} else {
shouldAnimateFlag = true;
ivBell.startAnimation(rotateAnimationRight);
}
}
});
}
}
Upvotes: 1