我使用GLSurfaceView.RENDERMODE_WHEN_DIRTY模式来更新我的glSurfaceView。
要绘制平滑的动画,我需要一些控制器,它将以恒定的帧速率更新表面视图。我知道我可以用Looper类实现这一点,但我相信必须有本地方式来做到这一点。我真的需要一些东西像:
Animation anim=new Animation(..);
anim.setListener(this);
anim.start();
...
private void onNextFrame(float pos) {
//do my animation according to position value
}
private void onAnimFinished() {
//animation is finished
}
UPD:已解决,请参阅我的回答。
答案 0 :(得分:0)
解决了以下类:
package tween_test;
import android.os.SystemClock;
public class Tween extends Thread {
public interface OnTweenUpdate {
public void onNextFrame(Tween tween,float position);
public void onTweenFinish(Tween tween);
}
public enum Easing {
REGULAR;
}
public enum Types {
LINEAR(1000, false,Easing.REGULAR);
private final long duration;
private final boolean looped;
private final Easing easing;
Types(long duration, boolean looped,Easing easing) {
this.duration = duration;
this.looped = looped;
this.easing=easing;
}
public Easing easing() {
return this.easing;
}
public long duration() {
return this.duration;
}
public boolean looped() {
return looped;
}
}
private final int FPS=60;
private final int FRAME_DELTA=1000/FPS;
private long lastFrameTimestamp;
private OnTweenUpdate listener;
private Types type;
private long startTS;
public Tween(Types type) {
super();
this.type=type;
}
public void setListener(OnTweenUpdate listener) {
this.listener=listener;
}
@Override
public void start() {
lastFrameTimestamp=startTS=SystemClock.elapsedRealtime();
super.start();
}
@Override
public void run() {
while (!isInterrupted()) {
long cts= SystemClock.elapsedRealtime();
if (cts-lastFrameTimestamp>=FRAME_DELTA) {
lastFrameTimestamp=cts;
if (listener!=null)
listener.onNextFrame(this,ease((float)(cts-startTS)/type.duration()));
}
if(cts>=startTS+type.duration()) {
boolean looped=type.looped();
if (!looped) {
if (listener != null)
listener.onTweenFinish(this);
this.interrupt();
} else {
lastFrameTimestamp=startTS=cts;
}
}
}
}
public void fforward() {
if (listener!=null)
listener.onTweenFinish(this);
this.interrupt();
}
private float ease(float pos) {
switch (type.easing()) {
case REGULAR:
return pos;
}
return 0f;
}
}