2010-08-20 130 views
11

我知道如何设置和显示椭圆形状。我知道如何在这个形状上应用渐变。我无法弄清楚的是我如何获得椭圆形渐变以匹配形状。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> 

如果你可以想象,这个渐变在中间有一个半透明的白色辉光,然后在边缘淡出到alpha零。我需要让它呈椭圆形,而不仅仅是一个圆形的渐变。我怎样才能做到这一点?

回答

2

这很困难,因为以这种方式定义的drawable在运行时绘制它们自己,以适应您将它们放入的空间。最佳解决方案,如果您必须在代码中执行此操作,将采用您已定义的可绘制形状XML并将其绘制到画布上或作为完美的圆形绘制到位图中。此时,渐变图案将遵循形状轮廓。一旦形状被绘制到静态上下文中,您可以将该形状添加到视图中(作为背景,比方说),当它尝试适合视图边界时,会将其变形为椭圆形。既然你有一张图片,整个事情就会按比例扭曲。

有希望的是,这种方法不会像素太差。

+0

标记正确的“如果你必须在代码中这样做”。我发现它比图像更容易和质量更高,这让我想起了这一点。 – coneybeare 2010-08-25 15:01:32

+0

这是我的实现你的想法:http://stackoverflow.com/questions/40811308/memory-heavy-oval-gradient – Mariusz 2016-11-25 20:19:15

0

做一个“哑巴但是工作”的方法是绘制椭圆轮廓​​,然后绘制大量嵌套的椭圆,它们具有相同的“中心”,其大小和颜色随着椭圆变小而变化,一直到一个像素的椭圆。 如果您自定义您的渐变代码,请插入HSV中的颜色,而不是RVB中的颜色!

+0

这一建议将工作正常,但警告说,每次添加层是另一层你的GPU具有绘制到屏幕上。我尝试过这一次,整个应用程序停下来。 – Yervant 2016-10-04 18:20:49

3

我会建议更多的'直接'绘图方法。如果你能画出渐变逐像素,那么你只需要记住,对于

  • 渐变色是成正比r
  • 椭圆(椭圆形)渐变色成正比r1+r2

这里:

的R - 距离圆心

R1,R2 - 距离椭圆的两个焦点

编辑: 考虑这个的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; 
} 

你会得到椭圆形类似的东西: alt text

好运气

+0

这也许可以确定,但它看起来很昂贵。 – coneybeare 2010-08-29 22:32:48

+0

这取决于如何执行每像素计算。如果它在GPU一侧执行(如梯度计算像素着色器) - 那么它就像闪电般快速:) – 2010-08-30 07:06:08

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"/>