2012-09-16 17 views
14

Estoy tratando de implementar un selector de color para mi aplicación de Android, y me encontré con un extraño problema en Android 4.1.1. El siguiente código no crea los gradientes esperados en Android 4.1.1, pero lo hace en 2.3.7:Problema con ComposeShader en 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); 

Aquí está el problema: enter image description here

(omitir el cuadro rojo a continuación en Android 4.1.1. Acabo de hablar sobre el gradiente anterior)

Cualquier idea ¿qué pasa? Creo que falta algo en mi código, pero no tengo ni idea de qué.

editar # 1: Si sólo tiene que utilizar para whiteMasksetShader, yo también obtener resultados diferentes para los dos sistemas: 2.3.7 Por lo que puedo ver el texto del menú de configuración (que está detrás de la ventana emergente) que brilla a través del rectángulo degradado. Además, hay un gradiente desde el borde superior izquierdo al borde inferior derecho (negro a blanco), pero el gradiente en el 4.1.1 va horizontalmente de izquierda a derecha. Por lo tanto, parece que hay un problema con ComposeShader

editar # 2: me encontré con un ejemplo más simple para describir el 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); 

Por lo tanto, tenemos sólo un gradiente lineal vertical desde cualquier color a negro y un degradado lineal horizontal de negro a blanco. Si multiplicamos estas dos capas, deberíamos obtener el rectángulo correcto (como en la captura de pantalla de la izquierda de arriba). Pero en Android 4.1.1 solo veo el gradiente de shader2. También probé esto en Gimp con dos capas y el resultado fue el mismo que en Android 2.3.7.

Respuesta

19

Encontré el problema: parece que tiene que ver con la aceleración de hardware. Como se describe here 'ComposeShader solo puede contener sombreadores de diferentes tipos (un BitmapShader y un LinearGradient por ejemplo, pero no dos instancias de BitmapShader)'. Pero, 'Si su aplicación se ve afectada por alguna de estas características o limitaciones faltantes, puede desactivar la aceleración de hardware solo para la parte afectada de su aplicación llamando al setLayerType(View.LAYER_TYPE_SOFTWARE, null). '

vi, que este método está disponible desde el SDK 11. Mi aplicación es compatible con todas las versiones que comienzan con SDK 7, así que tengo que comprobar si el método está disponible:

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

Ahora todo está bien.

+0

¿Se aplica la aceleración de hardware por defecto? No encontré esta información en el enlace proporcionado por usted. – Marek

+0

No estoy seguro, pero creo y espero que sí :-) –

+2

También hay 'ViewCompat.setLayerType (ver, View.LAYER_TYPE_SOFTWARE, null);' method/call en la biblioteca support-v4. – Mavrik

Cuestiones relacionadas