我需要在Android应用中运行复杂的自定义动画。为此,我编写了一个需要重复调用的函数,并使用当前时间戳来计算屏幕上View元素的位置,颜色,阴影等。
我可以使用一大堆不同的方法来调用此函数:
在我目前的实现中,我只是通过runOnUIThread从一个单独的线程调用我的动画函数。虽然它有效,但它似乎不是一个好主意,因为它可能会使事件队列充满信息,而不是可以处理或者在屏幕刷新时需要消息......
我在几个小时后发布了similar question for iOS并且@IanMacDonald为我提供了一个惊人的答案,它允许在每次屏幕刷新之前调用我的功能一次,它可以制作出非常流畅的动画。有没有类似我在Android中可以做的事情,即每次屏幕即将刷新时都调用我的函数?
如果可能,我想使用尽可能向后兼容的方法,最好是API 7或更低版本......
答案 0 :(得分:1)
我做了一些阅读,似乎目前首选的方法是使用Choreographer's postFrameCallback方法。不幸的是,Choreographer仅在API 16中添加,这对我的用例来说有点过于严格。
通过"递归"这是一种方法。 View.postDelayed调用(即Runnable将自行重新发出View.postDelayed),延迟时间为Display.getRefreshRate:
import android.app.Activity;
import android.view.Display;
import android.view.View;
public abstract class DisplayRefreshTimer implements Runnable {
public DisplayRefreshTimer(final View view) {
Activity activity = (Activity) view.getContext();
Display display = activity.getWindowManager().getDefaultDisplay();
final int delay = (int) (1000 / display.getRefreshRate());
view.postDelayed(new Runnable() {
@Override
public void run() {
view.postDelayed(this, delay);
DisplayRefreshTimer.this.run();
}
}, delay);
}
}
要使用它,只需对其进行子类化,覆盖run()
并实例化将其传递给当前视图:
new DisplayRefreshTimer(currentView) {
@Override
public void run() {
// Do your magic here...
}
};
如果你的目标是API 17+,你可以使用View.getDisplay而不是通过活动,但是你可能会像上面提到的那样关注Choreographer。
请不要让这个初步答案阻止您发布其他想法。如果有更好的解决方案仍然隐藏在某处,我不会感到惊讶。也许在OpenGL框架中?乍一看,我无法找到任何东西,但我也一直在寻找。