Androidanimation:等到完成?

在继续执行程序之前,我希望等待一个Android ImageView中的animation完成*,那么执行此操作的正确方法是什么?

  • (在这种情况下,“完成”意味着它贯穿其所有的帧一次,并在最后一帧停止。我不清楚这个animation是否是一个android:oneshot =“true”animation,因为我将使用它多个次,但不会连续运行,而是间歇运行)

研究/猜测:

答:在心脏我的问题似乎是一个Java线程的问题,因为Android AnimationDrawable实现Java.lang.Runnable 。 所以也许线程是解决scheme。 也许答案会包括join ?

B.其他人的做法似乎一直使用AnimationListener ,这对于我的简单需求来说似乎很困难和不必要的复杂。 另外我不确定如何去做。

C. AnimationDrawable类有一个(boolean)isRunning方法,可以在while循环中使用(即while(anim.isRunning()){wait(100ms)})。 但我有一种直觉,认为这是错误的做法。 尽pipe似乎在并发教程中提到了类似的东西

代码片段

this.q_pic_view.setImageResource(0); this.q_pic_view.setBackgroundResource(R.drawable.animation_test); AnimationDrawable correct_animation = (AnimationDrawable) this.q_pic_view.getBackground(); correct_animation.start(); //here I tried to implement option C but it didn't work while(correct_animation.isRunning()){ try { Thread.sleep(20); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } 

animation

 <?xml version="1.0" encoding="utf-8"?> <animation-list android:id="@+id/AnimTest" android:oneshot="true" xmlns:android="http://schemas.android.com/apk/res/android"> <item android:drawable="@drawable/animtest001" android:duration="33"/> <item android:drawable="@drawable/animtest002" android:duration="100"/> <item android:drawable="@drawable/animtest003" android:duration="66"/> <item android:drawable="@drawable/animtest004" android:duration="66"/> <item android:drawable="@drawable/animtest005" android:duration="33"/> <item android:drawable="@drawable/animtest006" android:duration="66"/> <item android:drawable="@drawable/animtest007" android:duration="33"/> <item android:drawable="@drawable/animtest008" android:duration="66"/> <item android:drawable="@drawable/animtest009" android:duration="100"/> <item android:drawable="@drawable/animtest010" android:duration="100"/> </animation-list> 

一个可能的方法来达到预期的效果,虽然不是我的问题的答案,但通过做这样的事情来延迟执行进一步的代码:

 int duration = 0; //Add all of the frames together for (int i=0; i<my_animation.getNumberOfFrames(); i++){ duration = duration + correct_animation.getDuration(i); } //delay the execution Handler handler = new Handler(); handler.postDelayed(new Runnable(){ public void run() { DoYourNextStuff(); } }, duration); //delay is here 

编辑:有很多方法来解决这个问题,给出的答案可能确实解决了我没有testing它的问题,但我最终只是等待了正确的时间量(起初),然后我改为使用asynchronous任务(它有一个完成的处理方法),并直接在asynchronous任务的updateProgress调用中运行我的animation。 在上一次迭代中,我使用螺纹表面视图来运行animation。 这最后一种方式是最快和最好的(因为在这篇文章中被问到的其他原因)。 我希望它可以帮助别人。

Solutions Collecting From Web of "Androidanimation:等到完成?"

build议你

  • 创build一个对象来封装“animation”的生命周期
  • 在对象中,你将有一个线程或一个计时器
  • 提供方法start()animation和awaitCompletion()
  • 使用private final Object completionMonitor字段来跟踪完成, synchronize它,并使用wait()notifyAll()来协调awaitCompletion()

代码片段:

 final class Animation { final Thread animator; public Animation() { animator = new Thread(new Runnable() { // logic to make animation happen }); } public void startAnimation() { animator.start(); } public void awaitCompletion() throws InterruptedException { animator.join(); } } 

您也可以使用一个ThreadPoolExecutor与单个线程或ScheduledThreadPoolExecutor ,并捕获animation的每个帧作为一个Callable 。 提交Callable的序列并使用invokeAll()CompletionService来阻止感兴趣的线程,直到animation完成。

最简单的方法是将一个(延迟的)Runnable发布到UI线程:

 Animation fadeout = new AlphaAnimation(1.f, 0.f); fadeout.setDuration(500); view.startAnimation(fadeout); view.postDelayed(new Runnable() { @Override public void run() { view.setVisibility(View.GONE); } }, 500); 

这将无痛地做到这一点。 永远(永远,永远,永远!)尝试阻止Android中的UI线程。 如果你这样做,电话冻结,你不会看到animation。 如果您需要等待一段时间,请使用另一个线程。

使用animation侦听器来侦听animation生命周期钩子。

 Animation fadeout = new AlphaAnimation(1.f, 0.f); fadeout.setDuration(500); final View viewToAnimate = view; fadeout.setAnimationListener(new AnimationListener(){ @Override public void onAnimationStart(Animation animation){} @Override public void onAnimationRepeat(Animation animation){} @Override public void onAnimationEnd(Animation animation){ viewToAnimate.setVisibility(View.GONE); } }); view.startAnimation(fadeout); 

嗨另一种select是使用ObjectAnimator 。 正如别人提到,你将不得不使用Listner

 //get an image resource ImageView imgView = (ImageView) findViewById(R.id.some_image); //create and init an ObjectAnimator ObjectAnimator animation; animation = ObjectAnimator.ofFloat(imgView, "rotationY", 0.0f, 360f); //set the duration of each iteration animation.setDuration(1500); //set number of iterations animation.setRepeatCount(1); //set setInterpolator animation.setInterpolator(new AccelerateDecelerateInterpolator()); //Add a listner to check when the animation ends animation.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { //postFirstAnimation(): This function is called after the animation ends postFirstAnimation(); } }); //start the animation animation.start();