2011-12-31 18 views
14

sto cercando di animare due strati di un disegnabile per ottenere l'effetto di l'indicatore di avanzamento indeterminata post-nido d'ape. L'XML è molto semplice ma sembrerebbe che solo un livello si animerà quando viene eseguito su piattaforme precedenti a Honeycomb.Anima due strati Articoli Drawable pre-Honeycomb

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_outer_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="1080" /> 
    </item> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_inner_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="720" 
      android:toDegrees="0" /> 
    </item> 
</layer-list> 

E` semplicemente una limitazione di queste piattaforme o c'è una sintassi alternativa che posso usare (in generale o specificamente mirato alla pre-API11) per ottenere la funzionalità desiderata?

risposta

11

v'è infatti una limitazione della piattaforma, anche se non è quello che si potrebbe pensare. Il problema è che il pre-API11, RotateDrawable avevano codice grezzo per richiedere che l'animazione ruotare in senso orario controllando se toDegrees era superiore fromDegrees; se no, i due erano forzati uguali tra loro. Se hai modificato il tuo esempio per far muovere il secondo oggetto in avanti (da 0 a 720 o anche da -720 a 0), entrambe le immagini si animerebbero bene su tutte le piattaforme; anche se mi rendo conto che sconfigge lo scopo di ciò che stai mirando.

Dai un'occhiata alla versione cache di Google Codesearch ha RotateDrawable.inflate(), che è la versione 2.3 del metodo utilizzato per trasformare l'XML nell'oggetto, e vedrai cosa intendo.

RotateDrawable.java ... il codice incriminato è intorno alla linea 235 ...

float fromDegrees = a.getFloat(
      com.android.internal.R.styleable.RotateDrawable_fromDegrees, 0.0f); 
    float toDegrees = a.getFloat(
      com.android.internal.R.styleable.RotateDrawable_toDegrees, 360.0f); 

    toDegrees = Math.max(fromDegrees, toDegrees); //<--There's the culprit 

Questo richiede un blocco di XML come il secondo elemento che hai lì, e lo trasforma in un RotateDrawable che finisce con il stesso valore per fromDegrees e toDegrees (nel tuo caso, 720), che causa l'immagine di stare semplicemente fermo. È possibile testare questo aspetto impostando il valore iniziale su un valore diverso da un multiplo di 360 (come 765). Vedrai che l'immagine continua a non animare, ma viene ruotata sulla coordinata iniziale.

Questo controllo imbarazzante è stata rimossa nelle fonti/ICS a nido d'ape, che è il motivo per cui si può fare a ritroso rotazione su queste piattaforme. Inoltre, non sembra che ci sia un modo per impostare questi valori dal codice Java, in modo da una consuetudine RotateDrawableCompat potrebbe essere nel tuo futuro :)

HTH

+1

Ottima conoscenza del funzionamento interno. Grazie! –

+0

collegamento di riferimento Aggiornamento: https://github.com/android/platform_frameworks_base/blob/android-2.3.7_r1/graphics/java/android/graphics/drawable/RotateDrawable.java#L230-235 –

1

sembra la soluzione rapida e sporca per ottenere questo lavorare in pre-nido d'ape è semplicemente capovolgere il da e al secondo ruotare. Questo non è l'ideale ma almeno la cosa gira intorno (anche se è un po 'più "noiosa"). Ecco come l'ABS sembra averlo risolto.

<layer-list xmlns:android="http://schemas.android.com/apk/res/android"> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_outer_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="1080" /> 
    </item> 
    <item> 
     <rotate 
      android:drawable="@drawable/abs__spinner_48_inner_holo" 
      android:pivotX="50%" 
      android:pivotY="50%" 
      android:fromDegrees="0" 
      android:toDegrees="720" /> <!-- Like this --> 
    </item> 
    </layer-list> 
Problemi correlati