Android动画:等到完成?
-
24-10-2019 - |
题
我想等到动画完成*在Android ImageView中完成*之前继续执行程序后,正确执行此操作的方法是什么?
- (在这种情况下,“完成”意味着它完全贯穿其所有帧,并在最后一个框架上停止。我不清楚此动画是否将是Android:onsehot =“ true”动画,因为我会多次使用它时间,但不会连续运行,但间歇性地运行)
研究/猜测:
答:我的问题似乎是一个Java线程问题,因为Android AnimationDrawable 工具 java.lang.runnable. 。因此,也许线程是解决方案。也许答案将包括 加入?
B.他人的方法似乎是在使用 AnimationListener, ,对于我的简单需求,这似乎很困难且不必要。另外,我不确定该怎么做。
C. AnimationDrawable 类具有(布尔)的iSrunning方法,可以在一段时间内使用(即(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
编辑:解决此问题有很多方法,给出的答案可能确实解决了问题 我没有测试, ,但是我最终只是等待了正确的时间(首先),然后我更改为使用异步任务(具有完成处理程序的方法),然后直接在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()
或a CompletionService
阻止您感兴趣的线程,直到动画完成。
其他提示
最简单的方法是发布一个可运行到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);
嗨,另一个选择是使用 objectanimator. 。再次,正如其他人提到的那样,您必须使用列表者
//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();