Java Android动画:等待完成?

Java Android动画:等待完成?,java,android,concurrency,android-animation,Java,Android,Concurrency,Android Animation,我想在Android ImageView中等待动画完成后再继续执行程序,正确的方法是什么 (在此上下文中,“已完成”表示它只在所有帧中运行一次,并在最后一帧停止。我不清楚此动画是否为android:oneshot=“true”动画,因为我将多次使用它,但它不会连续运行,而是间歇运行) 研究/猜测: 答:在本质上,我的问题似乎是一个Java线程问题,因为Android实现了。因此,也许线程是解决方案。也许答案包括 B.其他人的方法似乎一直在使用,对于我的简单需求来说,这似乎很困难,而且不必要地

我想在Android ImageView中等待动画完成后再继续执行程序,正确的方法是什么

  • (在此上下文中,“已完成”表示它只在所有帧中运行一次,并在最后一帧停止。我不清楚此动画是否为android:oneshot=“true”动画,因为我将多次使用它,但它不会连续运行,而是间歇运行)
研究/猜测:

答:在本质上,我的问题似乎是一个Java线程问题,因为Android实现了。因此,也许线程是解决方案。也许答案包括

B.其他人的方法似乎一直在使用,对于我的简单需求来说,这似乎很困难,而且不必要地复杂。而且我也不知道该怎么做

C.该类有一个(布尔)isRunning方法,该方法可能用于while循环(即while(anim.isRunning()){wait(100ms)})。但我有一种直觉,这是错误的方法。虽然类似的东西似乎在书中提到过

代码片段

   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();
        }
    }
动画

<?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
int duration=0;
//将所有帧添加到一起
对于(inti=0;我建议您

  • 创建一个对象来封装“动画”生命周期
  • 在对象中,您将有一个线程或计时器
  • 提供方法来
    start()
    动画和
    awaitCompletion()
  • 使用
    private final Object completion monitor
    字段跟踪完成情况,
    对其进行同步,并使用
    wait()
    notifyAll()
    协调
    waitcompletion()
代码段:

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
一起使用,并将动画的每个帧捕获为
Callable
CompletionService
来阻止感兴趣的线程,直到动画完成。

最简单的方法是将一个(延迟的)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 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);

嗨,另一个选择是使用。同样,正如其他人提到的,你必须使用列表器

//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();

动画完成需要多少时间?CapDroid如果将上述xml片段中的所有整数相加,则可以得到动画的总持续时间。但我正在寻找一个通用解决方案,因此在这种情况下对我没有帮助。请尝试此线程。sleep(663);663=动画的总时间..回答得很好,不过我在运行中执行重载/数据库工作()时遇到了一个小问题,以及动画是否已结束的条件。
Animation.hasend()
它可能不会一直返回true。将
postDelayed
中的延迟毫秒数增加到动画持续时间,解决了问题:)此代码是史诗般的,非常小,工作起来非常有魅力!谢谢你的发帖!!我真的不相信这是一个好的解决办法。硬编码值很少被接受。我不知道这是一个如何被接受的最上等投票的答案。这显然是正确的。不管怎样,+1来自我。@katzenhut,因为在当前上下文中答案是错误的。OP使用的AnimationDrawable甚至不是从动画派生的。因此,如果您使用的是从animation类派生的动画,那么这个答案是正确的,但是对于AnimationDrawable,它是不正确的。AnimationDrawable在其生命周期方面没有像Animation类那样的回调。@Zainodis-android中奇怪的命名转换从未停止让我惊讶。。。但你是对的。谢谢你的澄清!