2016-11-14 98 views
1

我使用GLSurfaceView.RENDERMODE_WHEN_DIRTY模式更新我的glSurfaceView。android:固定幀率動畫

爲了繪製流暢的動畫,我需要一些控制器,它可以以一個固定的幀率更新表面視圖。我知道我可以用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

解決了以下類別:

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

真的應該在回答中(沒有問題)來描述的解決方案 - 這是完全有效的答案添加到自己的問題,然後接受它,如果你發現瞭解。此外,這不是一個真正的答案,它是另一篇文章的評論。 – EJoshuaS

+0

我沒有在評論中發佈它,因爲我不知道如何在評論中發佈代碼。代碼之前的很少空格不工作。代碼關鍵字也不起作用。例如'code'(這是我的代碼) – undefined

+0

爲什麼你認爲在起始帖子中解決問題的代碼不是答案? – undefined