2012-03-25 15 views
6

Ho diverse viste all'interno di FrameLayout. C'è una transizione che ho scritto in cui ogni vista ha una classe di animazione personalizzata applicata. Durante questa transizione, ho bisogno di portare la vista nella parte inferiore dell'ordine z in primo piano. Lo faccio con:Android View.bringToFront() provoca lo sfarfallio

public static void putBackAtFront(ViewGroup v) 
    { 
     v.getChildAt(0).bringToFront(); 
     refreshEverything(v); 
    } 

Questo viene chiamato dall'interno di applyTransformation() della mia animazione personalizzata.

cioè

public class PivotAnimation extends Animation { 
    private View view; 
    ... 
    @Override 
    protected void applyTransformation(float interpolatedTime, Transformation t) 
    { 
     ... 
     if(interpolatedTime >= 1.f && isAtBack(view)) 
     { 
      putBackAtFront(view); 
     } 
     ... 
    } 
    ... 
} 

refreshEverything() chiamate invalidate() e requestLayout() sul genitore FrameLayout e tutti i suoi figli.

Tutto funziona perfettamente tranne che quando viene chiamato putBackAtFront(), la vista che ora si trova nella parte inferiore scompare per un singolo fotogramma prima di riapparire all'istante, producendo uno sfarfallio notevole. Ho anche provato senza chiamare refreshEverything(), non fa differenza.

ho scelto come target API livello 7.

risposta

1

applyTransformation() viene chiamato più volte durante l'animazione così si dovrebbe fare l'animazione basato sul interpolatedTime, quando il suo 1.0, l'animazione è alla fine, in modo da dovrebbe chiamare il tuo portare qui davanti.

Quindi, a mio parere, questo sfarfallio si verifica quando in alcune di queste chiamate al metodo, getChildAt (0) ottiene una visualizzazione diversa da quella desiderata e viene visualizzato lo sfarfallio.

+0

Spiacente, ho aggiornato la mia domanda per chiarire. Sto già facendo come dici tu; putBackAtFront() viene chiamato una sola volta alla fine della transizione, non tutte le volte. –

0

sto pensando che deve essere una delle tre cose:

Se si sta costruendo con le API 3.0+, è possibile che l'accelerazione hardware abilitata. Anche questo è attivo per impostazione predefinita in 4.0. Puoi provare a utilizzare

setLayerType(LAYER_TYPE_SOFTWARE, null); 

per disabilitare l'accelerazione HW su tale layout/vista/finestra.

Inoltre, potrebbe non essere necessario chiamare requestLayout(), se tutte le viste sono figli di un relativelayout, una modifica di z-index non dovrebbe riguardarlo.

La chiamata invalidate potrebbe non essere necessaria. Hai provato a mettere a fuoco le viste e a chiamare semplicemente requestFocus() invece di bringToFront()? bringToFront() apparentemente rimuove la vista dal suo genitore e lo riaggiunge. Questo potrebbe facilmente causare una invalidazione tra i passaggi, poiché non penso che nulla stia mettendo in pausa il disegno mentre questo sta accadendo.

+0

Grazie per i suggerimenti. Come indicato nella domanda, sto puntando all'API 7 (2.1), quindi l'accelerazione HW non è un'opzione per me. requestFocus() non cambierà l'ordine z, che è necessario che accada. Anche come indicato nella domanda che ho provato con e senza requestLayout() e invalidate(). In ogni caso, bringToFront() viene chiamato sul thread UI (main) quindi, questo - secondo i documenti - dovrebbe per definizione "mettere in pausa" il disegno. A meno che i documenti non stiano raccontando la storia completa, e c'è un po 'di rendering asincrono in corso. –

Problemi correlati