2012-10-10 14 views
6

Uso le funzioni per canvas come drawCircle e drawPoint in Android. Questo funziona bene.Disegnare su una tela con ritardo - "make onDraw() slow down"

Ma il problema ora è disegnare questi diversi elementi con un ritardo, quindi sembra un'animazione.

Che tipo di meccanismo dovrei usare? Ho provato con async ma non mi piace quel modo di farlo.

Devo usare qualche tipo di timer che si limita a disegnare con un intervallo o ci sono altri modi intelligenti per farlo?

risposta

3

Io uso questa strategia, prima dichiaro un gestore e un Runnable in questo modo:

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

Poi quando voglio iniziare il mio manager volta mi basta chiamare il mTimeManager.run() e inizierà a notificare periodicamente i miei Observer s (aggiunti in precedenza).

Se avete bisogno per qualche motivo fermare il timer o qualcosa che hai appena fatto questo:

mHandler.removeCallbacks(mTimeManager); 

[EDIT - codice più completo]

Ok che cerchiamo di renderlo più chiaro, prima ho fatto un oggetto Observable personalizzato come quello [che è opzionale]:

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

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

la ragione di questo è proprio perché io non posso chiamare setChan ged() all'esterno della classe Observable: è protetto, se non viene modificato non notifica alcun osservatore.

Le altre dichiarazioni mantenere lo stesso come mostrato prima, ora ho bisogno di iniziare questa TimeManager da qualche parte, la mia app è un LiveWallpaper e faccio tutta roba di rendering in una classe che estende una Thread, ma non è necessario che necessariamente, ho fatto un metodo chiamato resumeDrawing(), questo è chiamato subito dopo super.start(); alla mia @Override di public synchronized void start() da Thread di classe, il metodo sembra che:

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

ed è duplice:

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

Ok, ora possiamo avviare e fermare il manager del tempo, ma chi sta ascoltando? Nessuno!add'em di modo da lasciare: sul costruttore del mio renderer aggiungo alcune Observer s al mio mObservable oggetto, una di queste è il renderer in sé, quindi il mio renderer estende 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 
     } 
    } 

per aggiungere osservatori voi semplicemente fare mObservable.addObserver(THE_OBJECT - Implements Observer)

si può vedere che non mi ri-renderizzare le mie cose ogni volta che sto avvertito, è perché io uso questo TimeManager per altro pensa che solo aggiornare la Canvas come l'aggiornamento della posizione degli oggetti che voglio disegnare solo internamente.

Quindi, ciò di cui hai bisogno per rallentare il disegno è cambiare il modo in cui gli oggetti cambiano internamente mentre il tempo passa, intendo le tue cerchie e punti ecc. Oppure puoi azzardare il tuo passo temporale, raccomando il primo.

Era più chiaro? Spero possa essere d'aiuto.

+0

thx, ma potresti pubblicare un esempio più completo? Mostrando l'implementazione. – FooBar

+0

Certo, sono al lavoro ora che è il pezzo di codice che potrei ricordare. Me ne vado tra 20 minuti, quindi APPENA POSSIBILE, ti darò un codice più completo. – HericDenis

+0

Ok @FooBar ora sono a casa ti aiuterò (: – HericDenis

1

Vorrei utilizzare un timer o creare animazioni. Puoi creare animazioni che faranno ogni genere di cose, compresa la modifica della trasparenza nel tempo.

Ecco il Android Documentation per le risorse di animazione

0

Credo che ci possono essere modi sofisticati di fare questo, ma per le mie esigenze ho usato un metodo semplice che ha un sacco di vantaggi: ho creo record delle coordinate (ed eventuali altri dati necessari) per ogni punto del disegno - invece di disegnare i punti sul posto - e quindi riprodurli usando un timer (gestore Android, preferibilmente). Questo offre anche molte possibilità durante il disegno: pausa, andare più veloce/più lento, andare indietro, ... Non so se questo metodo può essere usato per disegni complicati, ma va bene per disegnare forme, curve, superfici, ecc.

Problemi correlati