Android ImageViewでアニメーションが終了するまで待機してから、プログラムの実行を続行します。これを行う適切な方法は何ですか?
研究/推測:
A.心の中で私の質問はJavaスレッドの質問のようです。なぜなら、Android AnimationDrawable 実装 Java.lang .Runnable 。スレッドが解決策かもしれません。おそらく答えには join ?が含まれます。
B.他の人のアプローチは AnimationListener を使用することであったように思われますが、これは私の単純なニーズには難しく、不必要に複雑です。加えて、私はそれを行う方法が正確にわかりません。
C. AnimationDrawable クラスには(boolean)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>
私の質問への答えではありませんが、望ましい効果を達成するための1つの可能な方法は、次のようなことをして、さらなるコードの実行を遅らせることです:
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
編集:この問題を解決するには多くの方法がありますが、与えられた答えはおそらく問題を解決します私はそれをテストしませんでしたが、私はただ待っていました正しい時間(最初は)、次に非同期タスク(完了のためのハンドラーメソッドがあります)の使用に変更し、非同期タスクのupdateProgress呼び出しでアニメーションを直接実行しました。最後の反復では、スレッド化されたサーフェスビューを使用してアニメーションを実行しています。この最後の方法は断然最速かつ最高です(この投稿で質問された以外の理由で)。私はそれが誰かを助けることを願っています。
提案する
start()
アニメーションと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
を使用し、アニメーションの各フレームをCallable
としてキャプチャすることもできます。 Callable
sのシーケンスを送信し、invokeAll()
または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リスナーを使用して、アニメーションライフサイクルフックをリッスンします。
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);
こんにちは別の選択肢は 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();