2012-10-31 5 views
7

Ho letto su Property Animation e Hardware Acceleration ma sono ancora incerto quale sia il modo più efficiente per utilizzare le classi di animatori. (Per motivi di questa domanda non ho bisogno di supportare i dispositivi prima di Honeycomb. Quindi voglio utilizzare le classi animatore.)Qual è il modo ottimale per animare un disegnabile all'interno di una vista utilizzando le classi di animatori?

Ad esempio, supponiamo di avere una vista. In questa vista ho un BitmapDrawable che voglio sfumare. Ci sono anche molti altri elementi all'interno della vista che non cambieranno.

Quale proprietà o oggetto sarebbe meglio usare con l'animatore? Il drawable? Una vernice con cui sto disegnando la bitmap in onDraw? Qualcos'altro?

Come può essere fatto per essere più efficiente con l'accelerazione hardware? Sarà necessario richiamare invalido per ogni passo dell'animazione o esiste un modo per animare solo il drawable e non far ridisegnare completamente il resto della vista per ogni fase dell'animazione?

Immagino che immagino che un caso ottimale sarebbe il resto della vista che non deve essere completamente ridisegnato nel software, ma piuttosto l'accelerazione hardware che sbiadisce in modo efficiente il drawable.

Eventuali suggerimenti o indicazioni sugli approcci consigliati?

Grazie!

+0

Bene, penso che lo stiate chiedendo perché causa problemi. L'animazione probabilmente sta invalidando tutto ma potremmo trovare una soluzione alternativa se ci mostri la gerarchia della vista che hai. Si prega di specificare cosa si sta animando in esso. –

+0

No, non ho ancora scritto nulla, sto solo cercando di ottenere tutte le informazioni prima di me. :) – cottonBallPaws

+0

Beh, se l'animazione funziona bene su dispositivi medi, allora siamo a posto. Tuttavia, se è notevolmente pesante, anche dopo i soliti miglioramenti come l'accelerazione hardware (che potrebbe non essere sempre disponibile), si dovrebbe trovare la propria soluzione. Ad esempio, se si sta animando uno sfondo che causa l'invalidazione dell'intera gerarchia, si crea uno snapshot della gerarchia e si anima lo sfondo dietro di esso. In ogni caso, è essenzialmente la tua decisione se mettere lo sforzo in quanto probabilmente funzionerà con l'accelerazione hardware e sulla maggior parte dei dispositivi. (fiduciosamente :) –

risposta

4

Con l'uso degli Animatori di oggetti di proprietà, in pratica sono solo funzioni matematiche che ripetutamente chiamano un metodo "setN()" ogni X millisecondi dove "N" è la proprietà che si desidera modificare.

Nell'esempio fornito nel caso di alpha, entrambi richiederebbero una chiamata a invalidate() per ridisegnare la vista che si sta animando. La differenza è che quando chiami setAlpha() sull'oggetto View, chiama per te invalidate(). Se si dovesse impostare l'oggetto target sull'oggetto Paint utilizzato per disegnare il drawable, sarà comunque necessario chiamare invalidate() sullo View in modo che venga ridisegnato con i nuovi parametri Paint.

Idealmente si desidera impostare il target sul bambino di livello più alto che è possibile in modo che il ridisegno avvenga solo sulle viste che si desidera animare. Se si imposta la destinazione sulla vista radice, ad esempio, chiamerà invalidate() su ogni bambino nell'intero ViewGroup che a sua volta chiamerà draw() su ogni figlio nel ViewGroup. Se lo si imposta su un livello superiore ImageView, verrà ridisposto solo lo ImageView.

Per utilizzare al meglio l'hardware, è necessario utilizzare le proprietà del livello. Per prima cosa, devi decidere quale sarà la Vista genitore più in alto che vuoi animare. Se si desidera solo dissolvere lo Drawable, sarà il Drawable o contenente View. Se vuoi sbiadire tutto, allora sarà la vista radice. Qualsiasi cosa tu decida di animare verrà applicata allo View nel suo insieme in una volta.

Utilizzare setLayerType() nella visualizzazione padre appena prima di avviare Animator. Impostalo su View#LAYER_TYPE_HARDWARE. Quindi imposta AnimationListener e ripristina il LayerType su View#LAYER_TYPE_SOFTWARE o View#LAYER_TYPE_NONE al completamento dell'animatore.

myParentView.setLayerType(View.LAYER_TYPE_HARDWARE, null); 
myObjectAnimator.addListener(new ViewAnimator.AnimatorListener() { 
    public void onAnimationEnd(Animator animation) { 
    myParentView.setLayerType(View.LAYER_TYPE_NONE); 
    } 
    public void onAnimationRepeat(Animator animation) { 
    } 
    public void onAnimationStart(Animator animation) { 
    } 
    public void onAnimationCancel(Animator animation) { 
    myParentView.setLayerType(View.LAYER_TYPE_NONE, null); 
    } 
} 
myObjectAnimator.start(); 

In questo caso, se si dovesse tradurre myParentView utilizzando la proprietà translateX, allora metterà strato myParentView e tutti i suoi figli in un unico piano. Inseriscilo nella memoria dell'hardware. Traduci l'intera vista tutto in una volta. Quindi, al termine, rimuovere myParentView dalla memoria.

EDIT:

Una nota finale, Alpha seminano il terrore sulla CPU. Se hai qualcosa su half-alpha e lo traduci nella vista, sarà più difficile da renderizzare rispetto alla semplice conversione della vista. Usalo con parsimonia.

1

Forse è possibile sovrapporre una nuova vista (che contiene solo l'animatore) a quella originale. la nuova vista impostata su Trasparente.

il ripristino da eseguire non è valido per la nuova vista senza la vista originale.

1

Dopo aver esaminato le tue domande ti suggerisco di leggere questo standard document che è pulito per farti capire come usare correttamente invalidate(). In secondo luogo, ci sono diversi modi già forniti da API Android per lavorare con l'animazione in diverse situazioni.

Here, spero che la maggior parte dei vostri dubbi saranno chiariti. Si prega di passare attraverso le sottosezioni e blog correlati menzionati loro.

Spero che questo ti possa aiutare.

Problemi correlati