您的位置:首页 > 其它

安卓动画开始,暂停和停止

2016-01-13 12:26 351 查看
android 在3.0之前经常使用的tween animation在网上已经有人实现了动画的暂停效果,但是对于property animation的暂停尚未实现,由于项目需要,我将属性动画的暂停、停止、播放的三个操作整理如下

对于视图和属性动画的实例化和事件,请直接看代码

暂停animator首先要达到时间停止,把动画停留在某个时间点,继续播放的时候要从这个时间点继续执行。很幸运的是animator给U我们提供了setCurrentPlayTime的方法,但是这个方法只能让动画回到一个指定的时间点,然后继续执行,所以我们需要寻找一个机制,在动画到达下一个时间点之前,将动画的时间点重新设置到暂停的时间点。ValueAnimator提供了addUpdateListener的方法,我们定义一个AnimatorUpdateListener,在onAnimationUpdate中,调用setCurrentPlayTime回置到暂停的时间点即可。这个时候需要注意,直接调用setCurrentPlayTime会触发onAnimationUpdate会造成死循环,在这里需要使用CountDownTimer来调用setCurrentPlayTime来规避。

要暂停视图的状态就比较容易,同样我们在AnimatorUpdateListener中的onAnimationUpdate,做一些手脚。暂停的时候我们通过ValueAnimator.getAnimatedFraction(); 获取动画当前的状态值临时保存起来。并且在暂停的时候设置 停止状态的TimeInterpolator,在这个TimeInterpolator里面的getInterpolation方法我们直接返回之前临时保存的fraction,这样就能达到状态的暂停。

重新播放怎么办?

重新播放的时候我们要判断当前如果是暂停的状态,我们就需要将onAnimationUpdate中不再设置setCurrentPlayTime,同时去掉我们设置的暂停TimeInterpolator。

语言组织比较乱,还是直接上代码吧。

[mw_shl_code=java,true] TextView text;

Button btnPause;

Button btnStop;

Button btnPlay;

ObjectAnimator animator;

static final int ID_BTN_PLAY=1001,ID_BTN_PAUSE=1002,ID_BTN_STOP=1003;

MyAnimatorUpdateListener updateListener = new MyAnimatorUpdateListener();

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

//初始化页面视图,以及增加事件监听

LinearLayout container = new LinearLayout(this);

container.setOrientation(LinearLayout.VERTICAL);

container.setBackgroundColor(Color.rgb(192, 192, 192));

setContentView(container);

btnPlay = new Button(this);

btnPlay.setText("播放");

btnPlay.setId(ID_BTN_PLAY);

btnPlay.setOnClickListener(this);

container.addView(btnPlay);

btnPause = new Button(this);

btnPause.setText("暂停");

btnPause.setId(ID_BTN_PAUSE);

btnPause.setOnClickListener(this);

container.addView(btnPause);

btnStop = new Button(this);

btnStop.setText("停止");

btnStop.setId(ID_BTN_STOP);

btnStop.setOnClickListener(this);

container.addView(btnStop);

text = new TextView(this);

text.setText("我是文本");

container.addView(text);

animator = ObjectAnimator.ofFloat(text, "x", 0f,200f);

animator.setRepeatCount(ValueAnimator.INFINITE);

animator.setDuration(2000l);

//为了增加

animator.addUpdateListener(updateListener);

}

@Override

public void onClick(View v) {

int id = v.getId();

switch(id){

case ID_BTN_PLAY:

//如果已经暂停,是继续播放

if(updateListener.isPause)updateListener.play();

//否则就是从头开始播放

else animator.start();

break;

case ID_BTN_STOP:

//如果点击停止,那么我们还需要将暂停的动画重新设置一下

updateListener.play();

animator.end();

break;

case ID_BTN_PAUSE:

updateListener.pause();

break;

}

}

class MyAnimatorUpdateListener implements AnimatorUpdateListener{

/**

* 暂停状态

*/

private boolean isPause = false;

/**

* 是否已经暂停,如果一已经暂停,那么就不需要再次设置停止的一些事件和监听器了

*/

private boolean isPaused = false;

/**

* 当前的动画的播放位置

*/

private float fraction = 0.0f;

/**

* 当前动画的播放运行时间

*/

private long mCurrentPlayTime = 0l;

/**

* 是否是暂停状态

* @return

*/

public boolean isPause(){

return isPause;

}

/**

* 停止方法,只是设置标志位,剩余的工作会根据状态位置在onAnimationUpdate进行操作

*/

public void pause(){

isPause = true;

}

public void play(){

isPause = false;

isPaused = false;

}

@Override

public void onAnimationUpdate(ValueAnimator animation) {

/**

* 如果是暂停则将状态保持下来,并每个刷新动画的时间了;来设置当前时间,让动画

* 在时间上处于暂停状态,同时要设置一个静止的时间加速器,来保证动画不会抖动

*/

if(isPause){

if(!isPaused){

mCurrentPlayTime = animation.getCurrentPlayTime();

fraction = animation.getAnimatedFraction();

animation.setInterpolator(new TimeInterpolator() {

@Override

public float getInterpolation(float input) {

return fraction;

}

});

isPaused = true;

}

//每隔动画播放的时间,我们都会将播放时间往回调整,以便重新播放的时候接着使用这个时间,同时也为了让整个动画不结束

new CountDownTimer(ValueAnimator.getFrameDelay(), ValueAnimator.getFrameDelay()){

@Override

public void onTick(long millisUntilFinished) {

}

@Override

public void onFinish() {

animator.setCurrentPlayTime(mCurrentPlayTime);

}

}.start();

}else{

//将时间拦截器恢复成线性的,如果您有自己的,也可以在这里进行恢复

animation.setInterpolator(null);

}

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: