2016-11-14 4 views
1

J'utilise le mode GLSurfaceView.RENDERMODE_WHEN_DIRTY pour mettre à jour mon glSurfaceView. Pour dessiner des animations fluides, j'ai besoin d'un contrôleur qui mettra à jour la vue de surface à une fréquence d'images constante.Je sais que je peux y parvenir avec la classe Looper, mais je crois qu'il doit y avoir une façon native de le faire.Idéalement j'ai besoin quelque chose comme:android: animation de taux de rafraîchissement fixe

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: Résolu, voir ma réponse.

Répondre

0

résolu avec la classe suivante:

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

La solution devrait vraiment être décrit dans une réponse (pas la question) - il est parfaitement valide pour ajouter une réponse à votre question, puis l'accepter si vous avez trouvé la Solution. Aussi, ce n'est pas vraiment une réponse, c'est un commentaire sur un autre post. – EJoshuaS

+0

Je ne l'ai pas posté dans le commentaire car je ne sais pas comment poster du code dans le commentaire. Quelques espaces avant que le code ne fonctionne pas. Le mot-clé Code ne fonctionne pas non plus.Par exemple 'code' (ceci est mon code) – undefined

+0

Pourquoi pensez-vous que le code qui résout le problème dans le post de départ n'est pas une réponse? – undefined