Я хотел бы подождать, пока анимация закончится * в Android ImageView до продолжения выполнения программы, каков правильный способ сделать это?
- (в этом контексте "законченный" означает, что он проходит через все свои кадры ровно один раз и останавливается на последнем. Я не понимаю, будет ли эта анимация андроидом: onehot = "true", потому что я буду используя его несколько раз, но он не будет запускаться непрерывно, но с перерывами)
Исследования/Догадки:
а. На первый взгляд мой вопрос, кажется, вопрос Java-потока, потому что Android AnimationDrawable реализует Java.lang.Runnable. Поэтому, возможно, потоки являются решением. Возможно, ответ будет включать join?
В. Подход других, похоже, заключался в использовании AnimationListener, это кажется сложным и излишне сложным для моих простых потребностей. Плюс я не совсем уверен, как это сделать.
С. Класс AnimationDrawable имеет (boolean) метод isRunning, который, вероятно, можно использовать в цикле while (т.е. While (anim.isRunning() ) {ожидания (100мс)}). Но у меня есть ощущение, что это неправильный подход. Хотя что-то похожее упоминается в concurrency учебник
Фрагмент кода
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
Изменить: Есть много способов решить эту проблему, ответ, вероятно, решает проблему, которую я не тестировал, но в итоге я просто ожидал правильного количества времени (сначала), затем я перешел на использование задача async (которая имеет метод обработчика для завершения) и запускала мою анимацию в вызове updateProgress задачи async напрямую. В последней итерации я использую резьбовое представление поверхности для запуска анимации. Этот последний путь, безусловно, самый быстрый и лучший (по другим причинам, о которых спрашивали в этом сообщении). Надеюсь, это поможет кому-то.