2015-06-16 10 views
36

Sto utilizzando il nuovo TextInputLayout per racchiudere un EditText. Quando si determino un campo presenta un errore faccio la seguente:La colorazione DrawableCompat non funziona su pre-Lollipop

Drawable drawable = DrawableCompat.wrap(getEditText().getBackground()); 

DrawableCompat.setTintList(drawable, ColorStateList.valueOf(Color.RED)); 

Questo funziona su 5.0 e trasforma il rosso sottolineatura, ma non fa nulla su 4.4 o 4.1 dispositivi di test. Cosa mi manca qui? Sembra così semplice e secondo Google "funziona" ... abbastanza sicuro di avere l'ultima versione di esso pure:

compilazione 'com.android.support:design:22.2.0'

FWIW, se faccio setColorFilter invece di setTint funziona su tutte le piattaforme, ma poi ho problemi con l'andare via e non tornare non appena lo stato attivo è impostato/lasciato/etc ... Preferirei farlo con tinta (e davvero preferisco che la tinta si applichi agli stati di messa a fuoco e non di messa a fuoco se qualcuno cerca lol extra)

Grazie!

+0

Normalmente queste classi di compatibilità non fanno nulla. Guardano il livello dell'API ed è supportata la funzionalità rilevante, quindi se lo fanno non fanno semplicemente nulla. Basta guardare il codice sorgente e scoprirlo. Darei un'occhiata da solo, ma sono sul mio telefono proprio ora. –

+0

In altre parole esattamente il comportamento che stai vivendo. L'unica vera caratteristica della classe Compat è che puoi usarli senza doversi preoccupare della compatibilità. Tutto ciò che accade se qualcosa non è supportato non è nulla. Che, naturalmente, non può essere detto per la cosa reale. –

+0

Questo non è ciò che è richiesto qui però. DrawableCompat è specificamente detto per portare la tinta ai livelli API 4 e successivi. https://chris.banes.me/2015/04/22/support-libraries-v22-1-0/ –

risposta

65

Quando si chiama wrap(), l'originale Drawable viene inserito internamente in un nuovo DrawableWrapper che viene utilizzato per implementare la colorazione su dispositivi meno recenti. Quindi, per farlo funzionare è necessario impostare la tornata Drawable indietro al EditText:

final Drawable originalDrawable = editText.getBackground(); 
final Drawable wrappedDrawable = DrawableCompat.wrap(originalDrawable); 
DrawableCompat.setTintList(wrappedDrawable, ColorStateList.valueOf(Color.RED)); 
editText.setBackground(wrappedDrawable); 

Dalla versione 23.2.0 del libreria di supporto è possibile utilizzare anche setTint() invece di setTintList() per impostare un solo colore tinta senza dover creare un ColorStateList.

DrawableCompat.setTint(wrappedDrawable, Color.RED); 

Se si vuole garantire la compatibilità all'indietro oltre il livello di API 16 si esegue in un piccolo intoppo. setBackground() è stato aggiunto nel livello 16 dell'API ed è necessario chiamare lo setBackgroundDrawable() sui dispositivi precedenti. È meglio implementare un metodo di supporto che lo faccia per te:

public static void setBackground(View view, Drawable background) { 
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { 
     view.setBackground(background); 
    } else { 
     view.setBackgroundDrawable(background); 
    } 
} 
+0

Funziona a livello di API 23 ma non a livello di API 21. – toobsco42

+0

@ toobsco42 Questo semplicemente non è vero. Non capisco cosa pensi che non funzionerebbe su Lollipop o inferiore. Il codice in questa risposta funziona dal livello API 4 fino al 23. –

+0

Questo è quello che ho provato gist.github.com/lawloretienne/5703098d2d32ee92082a E solo sul livello API 21 non è stato colorato correttamente. – toobsco42