8

Sto usando setColorFilter per impostare il filtro colore di UNO dei miei pulsanti. Questo ha funzionato perfettamente fino all'aggiornamento di Android 5.0 Lollipop. Ora, il filtro colore sembra trapelare sugli altri miei pulsanti, anche quando chiudo l'attività e lo riapre (si reimposta se chiudo l'app e lo riapre).Lollipop Android 5.0: setColorFilter "perde" su altri pulsanti

mio styles.xml (V21): (lo stesso vecchio, tranne qui suo genitore è materiale, prima che fosse Holo)

<style name="Theme.FullScreen" parent="@android:style/Theme.Material.Light.NoActionBar.Fullscreen"> 
    <item name="android:buttonStyle">@style/StandardButton</item> 
    <item name="android:windowTranslucentStatus">true</item> 
</style> 

mio styles.xml (per tutte le versioni):

<style name="StandardButton" parent="android:style/Widget.Button"> 
    <item name="android:background">@android:drawable/btn_default</item> 
</style> 

My Button:

<Button 
    android:id="@+id/mainMenuButton"    
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:onClick="mainMenu" 
    android:text="@string/button_mainMenu" 
    android:visibility="gone" /> 

Il mio codice:

Button mainMenuButton = (Button) findViewById(R.id.mainMenuButton); 
mainMenuButton.getBackground().setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY)); 
mainMenuButton.setVisibility(View.VISIBLE); 

Il colore:

<color name="light_green">#5CD65C</color> 

Il risultato:

apro l'applicazione, quindi l'attività di gioco e tutti i pulsanti sono visualizzazione corretta. Premo il pulsante per impostare il filtro colore, tornare al menu principale e riaprire l'attività di gioco e ora tutti i pulsanti sono verdi.

Qualche idea?

risposta

1

OP qui. Grazie per i vostri suggerimenti. L'utilizzo del codice seguente ha risolto il problema.

Impostazione del filtro

Drawable background = getResources().getDrawable(android.R.drawable.btn_default); 
background.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY)); 
mainMenuButton.setBackground(background); // Use setBackgroundDrawable for API<16 
mainMenuButton.setVisibility(View.VISIBLE); 

Gli altri pulsanti non è diventato verde.

Cancellare il filtro

Cosa è successo dopo è stato, che sembrava che Android (in parte) ignorato la mia chiamata a cancellare il filtro colore (il che accade in seguito nel codice). "In parte", perché era verde, ma quando l'ho premuto, è diventato giallo (che è il comportamento btn_default rispetto al verde scuro con il filtro). Per risolvere questo problema, ho dovuto cambiare il mio ordine funzione di chiamata al seguente:

mainMenuButton.setVisibility(View.VISIBLE) 
mainMenuButton.getBackground().clearColorFilter(); 
mainMenuButton.invalidate(); 

NOTA: Questo però invertito il comportamento del pulsante. Quando premo (e ti tengo premuto) sul pulsante, sembra avere ancora il comportamento del filtro di colore verde su di esso e diventa verde scuro. Quando lo rilascio, torna ad essere grigio secondo btn_default. Qualche suggerimento su questo?

Spero che questo almeno in qualche modo aiuti qualcun altro con questo strano problema, che per me si è verificato solo su Android 5.0 Lollipop API livello 21. (Ho testato API 8, 9, 12, 13, 16, 17, 18 e 19 dove questo problema non si è verificato, inoltre non sembra essere ART con la sua compilazione AOT come mi aspettavo, dato che abilitare ART su un dispositivo Android 4.4.4 non ha causato questo problema.) Stranamente, mutate() non ha funzionato neanche, come mi sarei aspettato.

1

L'istanza del drawable è condivisa tra tutti i pulsanti, quindi l'impostazione di un filtro del colore cambia tutti (non si vedono immediatamente le modifiche perché i pulsanti non vengono invalidati immediatamente).

Provare a caricare manualmente il drawable (BitmapFactory.decodeResource(getResources(), android.R.drawable.btn_default, null)) e impostarlo come sfondo del pulsante.

19

Il problema è che lo sfondo Drawable viene riutilizzato su molte viste. Per garantire che lo Drawable non sia condiviso tra più viste, è necessario utilizzare il metodo mutate.

Vedi: mutate()

codice Esempio:

Drawable background = mainMenuButton.getBackground(); 
background.mutate(); 
background.setColorFilter(new PorterDuffColorFilter(getResources().getColor(R.color.light_green), PorterDuff.Mode.MULTIPLY)); 
mainMenuButton.setBackground(background); 
+0

Quando ho letto la tua risposta sono saltato di gioia, poiché sembrava così semplice e intuitivo (non avevo mai sentito parlare di 'mutate()' prima). Mi sono precipitato al mio progetto e ho implementato la tua soluzione e purtroppo non funziona. Tutti i miei pulsanti diventano ancora verdi. Ho anche provato: 'background = background.mutate();' e quindi impostare il filtro su quello, ma i pulsanti diventano ancora verdi. Non so che altro provare (oltre a chiamare 'clearFilter()' su tutti gli altri pulsanti, che funziona, ma è davvero brutto da un codice). – Johis

Problemi correlati