【问题标题】:android:fixed frame rate animationandroid:固定帧率动画
【发布时间】:2016-11-14 10:52:17
【问题描述】:

我使用 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:已解决,请参阅我的答案。

【问题讨论】:

    标签: android animation frame-rate


    【解决方案1】:

    使用以下类解决:

    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;
          }
    }
    

    【讨论】:

    • 解决方案确实应该在答案(而不是问题)中描述 - 为您自己的问题添加答案然后在找到解决方案时接受它是完全有效的。另外,这不是真正的答案,而是对另一篇文章的评论。
    • 我没有在评论中发布它,因为我不知道如何在评论中发布代码。代码前的几个空格不起作用。代码关键字也不起作用。对于示例“代码”(这是我的代码)
    • 为什么你认为开头帖子中解决问题的代码不是答案?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多