tjb*_*tjb 31 java concurrency android android-animation
在继续执行程序之前,我想等到Android ImageView中的动画结束*,这样做的正确方法是什么?
研究/猜测:
答:我的问题似乎是Java线程问题,因为Android AnimationDrawable实现了Java.lang.Runnable.也许线程是解决方案.也许答案会包括加入?
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();
}
}
Run Code Online (Sandbox Code Playgroud)
动画
<?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>
Run Code Online (Sandbox Code Playgroud)
尽管不是我的问题的答案,但实现预期效果的一种可能方法是通过执行以下操作来延迟执行更多代码:
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
Run Code Online (Sandbox Code Playgroud)
编辑:有很多方法可以解决这个问题,给出的答案可能确实解决了我没有测试它的问题,但我最后只是等待了正确的时间(起初),然后我改为使用异步任务(它有一个完成的处理程序方法)并直接在异步任务的updateProgress调用中运行我的动画.在最后一次迭代中,我使用线程表面视图来运行动画.最后一种方式是迄今为止最快和最好的方式(出于那些在本文中提到的其他原因).我希望它对某人有帮助.
net*_*ist 51
最简单的方法是将(延迟的)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);
Run Code Online (Sandbox Code Playgroud)
那将无痛苦地完成这项工作.从来没有(永远,永远,永远!)尝试阻止Android中的UI线程.如果您这样做,手机会冻结,无论如何您都不会看到动画.如果您需要等待一段时间,请使用另一个线程.
小智 42
使用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);
Run Code Online (Sandbox Code Playgroud)
建议你
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();
}
}
Run Code Online (Sandbox Code Playgroud)
您也可以使用ThreadPoolExecutor单个线程或ScheduledThreadPoolExecutor,并将动画的每个帧捕获为Callable.提交Callables 序列并使用invokeAll()或CompletionService阻止感兴趣的线程直到动画完成.
| 归档时间: |
|
| 查看次数: |
53847 次 |
| 最近记录: |