Android: 指定时间后停止AnimationDrawable,恢复onResume(),暂停onPause()
Android: Stop AnimationDrawable after specified time, resume onResume(), pause onPause()
我需要在指定的时间后停止 AnimationDrawable
,但是 class 没有提供任何直接的方法。我还要求动画暂停 onPause()
回调并恢复 onResume()
回调。我在 Whosebug 中找不到任何复杂的答案,所以我决定写下我自己的答案。我希望它能帮助一些人。
这是我的代码。
实施:
/**
* Adds some new features which are not available in the {@link AnimationDrawable} class.
* The main difference is that this class allows setting a timer, which indicates for how
* long is the animation supposed to be rendered.
*/
public class CustomAnimation
{
//==============================================================================================
private AnimationDrawable animation;
//==============================================================================================
private Drawable currentFrame;
//==============================================================================================
private Callable<Void> afterDelay;
//==============================================================================================
private long lastCheckedTime;
private long duration;
//==============================================================================================
private Runnable animationFinished;
private Handler handlerAnimation;
//==============================================================================================
private boolean infinite;
/**
* @param animation the {@link AnimationDrawable} which is about to animate
*/
public CustomAnimation(AnimationDrawable animation)
{
this.animation = animation;
}
/**
* Sets a time limit after which is the animation finished.
* @param duration time in milliseconds. Set to -1 if the animation is infinite.
*/
public void setDuration(long duration)
{
this.duration = duration;
if(duration == -1) infinite = true;
}
/**
* Starts the animation from the first frame, looping if necessary.
*/
public void animate()
{
animation.start();
lastCheckedTime = System.currentTimeMillis();
stopAfterDelay();
}
/**
* Cancels the animation.
*/
public void cancel()
{
animation.stop();
if(handlerAnimation != null) handlerAnimation.removeCallbacks(animationFinished);
}
/**
* Pauses the animation.
*/
public void pause()
{
currentFrame = animation.getCurrent();
duration = getRemainingTime();
animation.setVisible(false, false);
}
/**
* Pauses the animation.
* Call this method only in the onPause() callback.
*/
public void onPause()
{
currentFrame = animation.getCurrent();
duration = getRemainingTime();
cancel();
}
/**
* Resumes the animation.
*/
public void resume()
{
if(!animation.isRunning())
{
lastCheckedTime = System.currentTimeMillis();
animation.setVisible(true, false);
setFrame();
stopAfterDelay();
}
}
/**
* Resumes the animation.
* Call this method only in the onResume() callback.
*/
public void onResume()
{
if(!animation.isRunning())
{
lastCheckedTime = System.currentTimeMillis();
animation.start();
setFrame();
stopAfterDelay();
}
}
/**
* Sets the callable method which is called right after the animation finishes.
* @param afterDelay the callable method which returns nothing
*/
public void setCallableAfterDelay(Callable<Void> afterDelay)
{
this.afterDelay = afterDelay;
}
/**
* @return remaining time in milliseconds until the animation is supposed to be finished
*/
public long getRemainingTime()
{
return duration - (System.currentTimeMillis() - lastCheckedTime);
}
private void stopAfterDelay()
{
if(infinite) return;
animationFinished = new Runnable()
{
@Override
public void run()
{
animation.stop();
try { if(afterDelay != null) afterDelay.call(); }
catch(Exception e) { e.printStackTrace(); }
}
};
handlerAnimation = new Handler();
handlerAnimation.postDelayed(animationFinished, duration);
}
private void setFrame()
{
for(int i = 0; i < animation.getNumberOfFrames(); i++)
{
Drawable checkFrame = animation.getFrame(i);
if(checkFrame == currentFrame) break;
animation.run();
}
}
}
用法:
发布:
CustomAnimation animation = new CustomAnimation((AnimationDrawable) img.getBackground());
animation.setDuration(5000);
animation.setCallableAfterDelay(new Callable<Void>()
{
@Override
public Void call()
{
img.setBackgroundResource(R.drawable.imgFinished);
return null;
}
});
animation.animate();
onPause()
回调:
@Override
public void onPause()
{
super.onPause();
animation.onPause();
}
onResume()
回调:
@Override
public void onResume()
{
super.onResume();
animation.onResume();
}
我需要在指定的时间后停止 AnimationDrawable
,但是 class 没有提供任何直接的方法。我还要求动画暂停 onPause()
回调并恢复 onResume()
回调。我在 Whosebug 中找不到任何复杂的答案,所以我决定写下我自己的答案。我希望它能帮助一些人。
这是我的代码。
实施:
/**
* Adds some new features which are not available in the {@link AnimationDrawable} class.
* The main difference is that this class allows setting a timer, which indicates for how
* long is the animation supposed to be rendered.
*/
public class CustomAnimation
{
//==============================================================================================
private AnimationDrawable animation;
//==============================================================================================
private Drawable currentFrame;
//==============================================================================================
private Callable<Void> afterDelay;
//==============================================================================================
private long lastCheckedTime;
private long duration;
//==============================================================================================
private Runnable animationFinished;
private Handler handlerAnimation;
//==============================================================================================
private boolean infinite;
/**
* @param animation the {@link AnimationDrawable} which is about to animate
*/
public CustomAnimation(AnimationDrawable animation)
{
this.animation = animation;
}
/**
* Sets a time limit after which is the animation finished.
* @param duration time in milliseconds. Set to -1 if the animation is infinite.
*/
public void setDuration(long duration)
{
this.duration = duration;
if(duration == -1) infinite = true;
}
/**
* Starts the animation from the first frame, looping if necessary.
*/
public void animate()
{
animation.start();
lastCheckedTime = System.currentTimeMillis();
stopAfterDelay();
}
/**
* Cancels the animation.
*/
public void cancel()
{
animation.stop();
if(handlerAnimation != null) handlerAnimation.removeCallbacks(animationFinished);
}
/**
* Pauses the animation.
*/
public void pause()
{
currentFrame = animation.getCurrent();
duration = getRemainingTime();
animation.setVisible(false, false);
}
/**
* Pauses the animation.
* Call this method only in the onPause() callback.
*/
public void onPause()
{
currentFrame = animation.getCurrent();
duration = getRemainingTime();
cancel();
}
/**
* Resumes the animation.
*/
public void resume()
{
if(!animation.isRunning())
{
lastCheckedTime = System.currentTimeMillis();
animation.setVisible(true, false);
setFrame();
stopAfterDelay();
}
}
/**
* Resumes the animation.
* Call this method only in the onResume() callback.
*/
public void onResume()
{
if(!animation.isRunning())
{
lastCheckedTime = System.currentTimeMillis();
animation.start();
setFrame();
stopAfterDelay();
}
}
/**
* Sets the callable method which is called right after the animation finishes.
* @param afterDelay the callable method which returns nothing
*/
public void setCallableAfterDelay(Callable<Void> afterDelay)
{
this.afterDelay = afterDelay;
}
/**
* @return remaining time in milliseconds until the animation is supposed to be finished
*/
public long getRemainingTime()
{
return duration - (System.currentTimeMillis() - lastCheckedTime);
}
private void stopAfterDelay()
{
if(infinite) return;
animationFinished = new Runnable()
{
@Override
public void run()
{
animation.stop();
try { if(afterDelay != null) afterDelay.call(); }
catch(Exception e) { e.printStackTrace(); }
}
};
handlerAnimation = new Handler();
handlerAnimation.postDelayed(animationFinished, duration);
}
private void setFrame()
{
for(int i = 0; i < animation.getNumberOfFrames(); i++)
{
Drawable checkFrame = animation.getFrame(i);
if(checkFrame == currentFrame) break;
animation.run();
}
}
}
用法:
发布:
CustomAnimation animation = new CustomAnimation((AnimationDrawable) img.getBackground());
animation.setDuration(5000);
animation.setCallableAfterDelay(new Callable<Void>()
{
@Override
public Void call()
{
img.setBackgroundResource(R.drawable.imgFinished);
return null;
}
});
animation.animate();
onPause()
回调:
@Override
public void onPause()
{
super.onPause();
animation.onPause();
}
onResume()
回调:
@Override
public void onResume()
{
super.onResume();
animation.onResume();
}