2012-09-16 19 views
14

Sto solo cercando di implementare un selettore di colori per la mia applicazione Android e ho riscontrato uno strano problema su Android 4.1.1. Il seguente codice non crea le pendenze previste su Android 4.1.1, ma lo fa in 2.3.7:Problema con ComposeShader su Android 4.1.1

Shader fadeInRight = new LinearGradient(0, 0, pWidth, 0, 0x00000000, 0xFF000000, Shader.TileMode.CLAMP); 
Shader blackToWhite = new LinearGradient(0, 0, 0, pHeight, 0xFF000000, 0xFFFFFFFF, Shader.TileMode.CLAMP); 
Shader whiteMask = new ComposeShader(blackToWhite, fadeInRight, PorterDuff.Mode.DST_IN); 
Shader blackToColor = new LinearGradient(0, 0, pWidth, 0, 0xFF000000, hue, Shader.TileMode.CLAMP); 
Shader shader = new ComposeShader(blackToColor, whiteMask, PorterDuff.Mode.SCREEN); 
paint.setShader(shader); 
... 
canvas.drawRect(new Rect(0, 0, pWidth, pHeight), paint); 

Ecco il problema: enter image description here

(ignorare il riquadro rosso in basso a Android 4.1.1. Parlo solo del gradiente sopra)

Qualche idea, cosa c'è che non va? Penso che manchi qualcosa nel mio codice, ma non ne ho idea, cosa.

EDIT # 1: Se mi basta usare whiteMask per setShader, ho anche ottenere risultati diversi per entrambi i sistemi: Sul 2.3.7 posso vedere il testo del menu di configurazione (che si trova dietro il popup) brilla attraverso il rettangolo del gradiente. Inoltre c'è un gradiente dal bordo in alto a sinistra al bordo in basso a destra (da nero a bianco), ma il gradiente sul 4.1.1 va in orizzontale da sinistra a destra. così sembra essere un problema con ComposeShader

EDIT # 2: ho trovato un esempio più semplice per descrivere il problema:

Shader shader1 = new LinearGradient(0, 0, 0, pHeight, hue, 0xffffffff, Shader.TileMode.CLAMP); 
Shader shader2 = new LinearGradient(0, 0, pWidth, 0, 0xff000000, 0xffffffff, Shader.TileMode.CLAMP); 
Shader shader = new ComposeShader(shader1, shader2, PorterDuff.Mode.MULTIPLY); 

Così, abbiamo solo una sfumatura lineare verticale dal qualsiasi colore al nero e un gradiente lineare orizzontale dal nero al bianco. Se moltiplichiamo questi due livelli, dovremmo ottenere il rettangolo corretto (come nell'immagine a sinistra sopra). Ma su Android 4.1.1 vedo solo il gradiente di shader2. Ho anche provato questo in Gimp con due strati e il risultato è stato lo stesso di Android 2.3.7.

risposta

19

Trovato il problema: sembra che abbia a che fare con l'accelerazione hardware. Come descritto here 'ComposeShader può contenere solo shader di tipo diverso (un BitmapShader e un linearGradient per esempio, ma non due istanze di BitmapShader). Ma, 'Se l'applicazione è interessata da una di queste funzionalità o limitazioni mancanti, è possibile disattivare l'accelerazione hardware solo per la parte interessata dell'applicazione chiamando setLayerType(View.LAYER_TYPE_SOFTWARE, null). '

ho visto, che questo metodo è disponibile dal SDK 11. My App supporta tutte le versioni che iniziano con SDK 7, quindi devo controllare se il metodo è disponibile:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { 
    setLayerType(View.LAYER_TYPE_SOFTWARE, null); 
} 

Ora va tutto bene.

+0

L'accelerazione hardware è applicata per impostazione predefinita? Non ho trovato queste informazioni nel link fornito da te. – Marek

+0

Non sono sicuro, ma penso e spero :-) –

+2

C'è anche 'ViewCompat.setLayerType (vista, View.LAYER_TYPE_SOFTWARE, null);' metodo/chiamata nella libreria di supporto-v4. – Mavrik

Problemi correlati