2010-08-20 15 views
11

Sé cómo configurar y mostrar una forma ovalada. Sé cómo aplicar un degradado a esta forma. Lo que no puedo entender es cómo puedo obtener un degradado ovalado que coincida con la forma.Gradiente Oval en Android

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android" 
     android:shape="oval" > 
    <gradient 
     android:startColor="#66FFFFFF" 
     android:endColor="#00FFFFFF" 
     android:gradientRadius="100" 
     android:type="radial" /> 
</shape> 

Si se puede imaginar, este gradiente tiene un brillo blanco semi transparente en el medio, luego se desvanece a alfa cero en los bordes. Necesito que salga en forma ovalada, no solo un degradado circular. ¿Cómo puedo conseguir esto?

Respuesta

2

Esto es difícil, ya que dibujables definidos de esta manera se dibujan en tiempo de ejecución, la adaptación al espacio de ponerlos en. La mejor solución, si debe hacer esto en el código, sería tomar la forma estirable que ha definido en XML y dibujarlo en un lienzo o en un mapa de bits como un círculo perfecto. En este punto, el patrón de degradado seguirá el contorno de la forma. Una vez que la forma se ha dibujado en un contexto estático, puede agregar la forma a una vista (como un fondo, digamos), que lo distorsionará en un óvalo cuando intente ajustarse a los límites de la vista. Como tienes una imagen, todo se distorsionará proporcionalmente.

Afortunadamente, no se pixelará demasiado mal con este método.

+0

Marcado correcto para "si debe hacer esto en el código". Descubrí que es mucho más fácil y de mayor calidad que una imagen, y esto me recordó esto. – coneybeare

+0

Esta es mi implementación de su idea: http://stackoverflow.com/questions/40811308/memory-heavy-oval-gradient – Mariusz

0

Una forma "tonto pero trabajando" para hacer esto sería para dibujar el contorno de su elipse, a continuación, una multitud de puntos suspensivos anidadas con el mismo "centro", cuyos tamaños y colores cambiar a medida que las elipses crecen más pequeño, todo el camino hasta una elipse de un píxel. Si personalizas tu gradiente, interpola los colores en HSV, ¡no en RVB!

+0

Esta sugerencia funcionaría bien, pero ten en cuenta que cada capa se agrega otra capa de la GPU tiene que sacar a la pantalla. Intenté esto una vez y toda la aplicación se detuvo. – Yervant

3

Sugeriría un enfoque de dibujo más 'directo'. Si se puede dibujar píxel por píxel gradiente, entonces es necesario sólo para recordar que para

  • círculo degradado de color es proporcional a r
  • elipse (ovalada) degradado de color es proporcional a r1+r2

aquí:

r - distancia al centro del círculo

R1, R2 - distancias a dos focos de la elipse

EDIT: consideran este código de Pixel Shader:

uniform sampler2D tex; 

void main() 
{ 
    vec2 center = vec2(0.5,0.5); 
    float len = 1.3*(distance(gl_TexCoord[0].xy,center)); 
    vec2 foc1 = vec2(len,0.); 
    vec2 foc2 = vec2(-len,0.); 
    float r = distance(center+foc1,gl_TexCoord[0].xy) + 
      distance(center+foc2,gl_TexCoord[0].xy); 
    float k = pow(r*0.9,1.3); 
    vec4 color = vec4(k,k,k,1.); 
    gl_FragColor = color; 
} 

Va a conseguir algo ovalada así: alt text

buena suerte

+0

Esto quizás podría estar bien, pero parece caro. – coneybeare

+0

Depende de cómo se realice el cálculo por píxel. Si se realiza en el lado de la GPU (como el cálculo del gradiente Pixel Shader), entonces es tan rápido como un rayo :) –

1
<?xml version="1.0" encoding="utf-8"?> 

<stroke android:width="1dp" android:color="#ffffffff" /> 

<size 
    android:width="40dp" 
    android:height="40dp"/> 

<gradient 
    android:type="radial" 
    android:startColor="#ffff0000" 
    android:endColor="#330000ff" 
    android:gradientRadius="40dp" 
    android:angle="270" 
    android:centerX=".5" 
    android:centerY=".5"/>