2012-10-10 16 views
6

Utilizo funciones para canvas como drawCircle y drawPoint en android. Esto funciona bien.Dibuje en un lienzo con retraso: "make onDraw() ralentice"

Pero el problema ahora es dibujar estos elementos diferentes con un retraso, por lo que parece una animación.

¿Qué tipo de mecanismo debo usar? He intentado con la sincronización, pero no me gusta esa forma de hacerlo.

¿Debo usar algún tipo de temporizador que solo dibuje con un intervalo o hay otras formas inteligentes de hacerlo?

Respuesta

3

utilizo esta estrategia, primero declara una Handler y un Ejecutable de esa manera:

private final Observable mObservable = new Observable(); 
    private final static int TIME_STEP_MS = 5; 
    private final Handler mHandler = new Handler(); 
    private final Runnable mTimeManager = new Runnable() 
    { 
     public void run() 
     { 
      mObservable.notifyObservers(TIME_STEP_MS); 
      mHandler.postDelayed(mTimeManager, TIME_STEP_MS); 
     } 
    }; 

Entonces cuando quiero empezar mi administrador de tiempo acabo de llamar la mTimeManager.run() y comenzará a notificar mi Observer s (previamente agregado) periódicamente.

Si necesita por alguna razón detener el temporizador o algo que acaba de hacer lo siguiente:

mHandler.removeCallbacks(mTimeManager); 

[EDIT - Código más completo]

Ok que vamos a hacerlo más claro, primero que hice un objeto personalizado observable como la [que es opcional]:

private final Observable mObservable = new Observable() 
    { 
     public void notifyObservers() 
     { 
      setChanged(); 
      super.notifyObservers(); 
     }; 

     @Override 
     public void notifyObservers(Object data) 
     { 
      setChanged(); 
      super.notifyObservers(data); 
     }; 
    }; 

la razón de esto es simplemente porque no puedo llamar setChan ged() fuera de la clase Observable - está protegido, si no se cambia no lo notifica a ningún observador.

Las otras declaraciones mantener el mismo que se muestra antes, ahora tengo que empezar este TimeManager en alguna parte, mi aplicación es un LiveWallpaper y hago todas las cosas de la representación en una clase que extiende un Thread pero no es necesario que, necesariamente, hice un método llamado resumeDrawing(), éste se llama justo después super.start(); en mi @Override de public synchronized void start() de Thread clase, el método parece que:

public void resumeDrawing() 
    { 
     if (!mTimeManagerRunning) // just a boolean field in my class 
     { 
      System.err.println("Resuming renderer."); // just for debug 
      mTimeManager.run(); 
      mTimeManagerRunning = true; 
     } 
     else 
     { 
      System.err.println("Renderer already running."); // just for debug 
     } 
    } 

y es doble:

public void pauseDrawing() 
    { 
     if (mTimeManagerRunning) 
     { 
      System.err.println("Pausing renderer."); 
      mHandler.removeCallbacks(mTimeManager); 
      mTimeManagerRunning = false; 
     } 
     else 
     { 
      System.err.println("Renderer already paused."); 
     } 
    } 

Ok, ahora podemos iniciar y detener el gestor de tiempo, pero ¿quién está escuchando? ¡Nadie!Así que vamos a add'em: En el constructor de mi Procesador añado algunas Observer s a mi objeto mObservable, uno de ellos es el procesador de sí mismo, por lo que mi procesador se extiende Thread e implementa Observer:

@Override // from Observer interface 
    public void update(Observable arg0, Object arg1) 
    { 
     mElapsedMsRedraw += (Integer) arg1; 

     if (mElapsedMsRedraw >= mDrawingMsPerFrame) 
     { 
      mElapsedMsRedraw = 0; 
      drawEm(); // refresh the canvas and stuff 
     } 
    } 

para añadir que los observadores simplemente haz mObservable.addObserver(THE_OBJECT - Implements Observer)

Puedes ver que no vuelvo a renderizar mis cosas cada vez que recibo una notificación, eso es porque utilizo este TimeManager para otras ideas además de actualizar el Canvas como actualizar la posición de los objetos que quiero dibujar solo internamente

Entonces, lo que necesita para ralentizar el dibujo es cambiar la forma en que sus objetos cambian internamente mientras pasa el tiempo, me refiero a sus círculos y puntos, etc., o puede dar el paso, recomiendo el primero.

¿Estaba más claro? Espero que ayude.

+0

thx, pero ¿podría publicar un ejemplo más completo? Mostrando la implementación. – FooBar

+0

Claro, estoy trabajando ahora, esa es la parte del código que puedo recordar. Me voy en 20 minutos, así que lo más pronto posible te daré un código más completo. – HericDenis

+0

Ok @FooBar ahora estoy en casa te ayudaré (: – HericDenis

1

Usaría un temporizador o crearía animaciones. Puede crear animaciones que harán todo tipo de cosas, incluida la modificación de la transparencia a lo largo del tiempo.

Aquí está la Android Documentation de Recursos de animación

0

Creo que puede haber formas sofisticadas de hacer esto, pero para mis necesidades que se utiliza un método simple que tiene un montón de ventajas: que creen en primer lugar registros de coordenadas (y cualesquiera otros datos necesarios) para cada punto del dibujo, en lugar de dibujar los puntos en el lugar, y luego reproducirlos usando un temporizador (controlador de Android, preferiblemente). Esto también ofrece muchas posibilidades en el dibujo real: pausa, avance más rápido/más lento, retroceda, ... No sé si este método se puede usar para dibujos complicados, pero está bien para dibujar formas, curvas, superficies, etc.