How to stop an animation (cancel() does not work)
Call clearAnimation()
on whichever View
you called startAnimation()
.
How to cancel an animation, but not to end it?
animation.cancel() is calling the animation listener as API documentation describes:
Cancelling an animation invokes the animation listener, if set, to
notify the end of the animation. If you cancel an animation manually,
you must call reset() before starting the animation again.
If you want different behaviour on cancel() and onAnimationEnd() i would suggest a boolean variable, which can be set on button click, and onanimationend checks whether it is true.
How to stop an animation onBackPressed?
Declare an Animation
object as a global
variable. Use cancel()
method to cancel the animation.
Try this:
// Animation
Animation animation;
............
..............
private void populateViewPager(List<Tab> tabs) {
.................
..............................
animation = AnimationUtils.loadAnimation(MainDrawerActivity.this, R.anim.tab_scale_up_down);
..............
.....................
}
@Override
public void onBackPressed() {
animation.cancel();
super.onBackPressed();
}
How to cancel current animation and immediately start new one with mouse event and requestAnimationFrame()
The question is why
Well, you seem to know why: you never stop your animation loop, so at every frame it will try to go to the mouse.clientN
position of when that animation loop started. Then at the next click, a second animation loop will start, running in parallel of the first one, and both will fight against each other to go toward their own mouse.clientN
position.
To avoid this situation, as you have identified, you can simply stop the previous loop by using cancelAnimationFrame
. All it takes is a variable accessible both to the animation scope and to the click handler.
However, keeping your animation loop going on is just killing trees. So make your code check if it has reached the target position before calling again requestAnimationFrame
from inside animation
.
const circle = document.querySelector("circle")
{
let anim_id; // to be able to cancel the animation loop
window.addEventListener("click", mouse => {
const animation = _ => {
const getCx = Number(circle.getAttribute('cx'))
const getCy = Number(circle.getAttribute('cy'))
const setCx = getCx + (mouse.clientX - getCx)/10;
const setCy = getCy + (mouse.clientY - getCy)/10;
circle.setAttribute("cx", setCx);
circle.setAttribute("cy", setCy);
// only if we didn't reach the target
if(
Math.floor( setCx ) !== mouse.x &&
Math.floor( setCy ) !== mouse.y
) {
// continue this loop
anim_id = requestAnimationFrame(animation);
}
}
// clear any previous animation loop
cancelAnimationFrame( anim_id );
anim_id = requestAnimationFrame(animation)
});
}
svg { border: 1px solid }
<svg viewBox="0 0 500 500" width="500" height="500">
<circle r="10" cx="100" cy="100" />
</svg>
How to stop animation in Android
An animation only moves the pixels on the screen, not the position of the object. To set your to stay where it upon end, set your
animation.setFillAfter(true);
To actually move the position of the object, look into using a modified version of the below code snippet.
MarginLayoutParams marginParams = new MarginLayoutParams(object.getLayoutParams());
marginParams.setMargins(left, (top+hol2), left, 0);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
object.setLayoutParams(layoutParams);
Regarding the onAnimationEnd being called multiple times, I would need to see some code.
The only two ways I know of to manually stop an animation would be
animation.cancel(); (may not work for 2.1, can't remember)
or
object.clearAnimation();
Sample Code Below:
upmotionleft = new TranslateAnimation(0, 0, 0, 600);
upmotionleft.setDuration(2000);
upmotionleft.setFillEnabled(true);
upmotionleft.setAnimationListener(new Animation.AnimationListener()
{
@Override
public void onAnimationStart(Animation animation)
{}
@Override
public void onAnimationEnd(Animation animation)
{
//sets to wherever I want the final object to be
MarginLayoutParams marginParams = new MarginLayoutParams(object.getLayoutParams());
marginParams.setMargins(left, top-hol2, left, 0);
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(marginParams);
object.setLayoutParams(layoutParams);
//starts next animation
object.startAnimation(nextAnimation);
}
@Override
public void onAnimationRepeat(Animation animation)
{}
});
object.startAnimation(upmotionleft);
This code is copied and pasted from a project of mine but it has been changed somewhat, should still run.
Android AnimatorSet.cancel() does not work on Marshmallow version devices
Try to modify your cancel()
method to this:
public void cancel() {
if (animatorSet != null) {
animatorSet.cancel();
}
if (next != null) {
next.cancel();
next = null;
}
}
It should work for API 23 also. If not, please share more code of your project to rebuild it and find another solution.
Related Topics
Estimating Beacon Proximity/Distance Based on Rssi - Bluetooth Le
How to Update/Refresh Specific Item in Recyclerview
Refreshing Activity on Receiving Gcm Push Notification
Adjust Icon Size of Floating Action Button (Fab)
Hardcoded String "Row Three", Should Use @String Resource
Support Library Vectordrawable Resources$Notfoundexception
How to Work with Android's In-App Update API
How to Implement Multi-Selection and Contextual Actionmode in Actionbarsherlock
Java.Lang.Illegalstateexception: the Specified Child Already Has a Parent
Find the Key Hash for a Signed App
How to Remove the Title Text from the Android Actionbar
Background Service Getting Killed in Android
How to Show Popupwindow at Special Location
How to Programmatically Log Out from Facebook Sdk 3.0 Without Using Facebook Login/Logout Button
How to Add Custom Font in React Native Android
Android: Is Using Setcontentview Multiple Times Bad While Changing Layouts