2012-01-27 100 views
21

我想创建一个逐渐从一种颜色变为另一种颜色的弧线(可变度数)。从例如,从蓝色到红色:

enter image description hereAndroid - 如何绘制基于渐变的弧线

这是我的代码:

SweepGradient shader = new SweepGradient(center.x, center.y, resources.getColor(R.color.startColor),resources.getColor(R.color.endColor)); 
Paint paint = new Paint() 
paint.setStrokeWidth(1); 
paint.setStrokeCap(Paint.Cap.FILL); 
paint.setStyle(Paint.Style.FILL); 
paint.setShader(shader); 
canvas.drawArc(rectF, startAngle, sweepAngle, true, paint); 

但结果是整个弧绘有相同的颜色。

编辑:
更多经过试验,我发现,颜色传播是由弧形的角度来确定。如果我绘制一个小角度的弧线,只显示第一种颜色。角度越大,画出的颜色越多。如果角度很小,似乎没有梯度。
这里是一个例子。我画弧4 - 90,180,270和360:

RectF rect1 = new RectF(50, 50, 150, 150); 
Paint paint1 = new Paint(); 
paint1.setStrokeWidth(1); 
paint1.setStrokeCap(Paint.Cap.SQUARE); 
paint1.setStyle(Paint.Style.FILL); 

SweepGradient gradient1 = new SweepGradient(100, 100, 
     Color.RED, Color.BLUE); 
paint1.setShader(gradient1); 

canvas.drawArc(rect1, 0, 90, true, paint1); 

RectF rect2 = new RectF(200, 50, 300, 150); 
Paint paint2 = new Paint(); 
paint2.setStrokeWidth(1); 
paint2.setStrokeCap(Paint.Cap.SQUARE); 
paint2.setStyle(Paint.Style.FILL); 

SweepGradient gradient2 = new SweepGradient(250, 100, 
     Color.RED, Color.BLUE); 
paint2.setShader(gradient2); 

canvas.drawArc(rect2, 0, 180, true, paint2); 

RectF rect3 = new RectF(50, 200, 150, 300); 
Paint paint3 = new Paint(); 
paint3.setStrokeWidth(1); 
paint3.setStrokeCap(Paint.Cap.SQUARE); 
paint3.setStyle(Paint.Style.FILL); 

SweepGradient gradient3 = new SweepGradient(100, 250, 
     Color.RED, Color.BLUE); 
paint3.setShader(gradient3); 

canvas.drawArc(rect3, 0, 270, true, paint3); 

RectF rect4 = new RectF(200, 200, 300, 300); 
Paint paint4 = new Paint(); 
paint4.setStrokeWidth(1); 
paint4.setStrokeCap(Paint.Cap.SQUARE); 
paint4.setStyle(Paint.Style.FILL); 

SweepGradient gradient4 = new SweepGradient(250, 250, 
     Color.RED, Color.BLUE); 
paint4.setShader(gradient4); 

canvas.drawArc(rect4, 0, 360, true, paint4); 

这里是结果:

enter image description here

这是令人惊讶的,因为我期望的RED是在弧线的起点,末端的蓝色以及两者之间的角度均匀分布,无论角度如何。
我试图空间的颜色使用手动位置参数,但结果是一样的:

int[] colors = {Color.RED, Color.BLUE}; 
float[] positions = {0,1}; 
SweepGradient gradient = new SweepGradient(100, 100, colors , positions); 

不知道如何解决这个问题?

回答

27

解决方法是设置BLUE的位置。这是像这样做:

int[] colors = {Color.RED, Color.BLUE}; 
float[] positions = {0,1}; 
SweepGradient gradient = new SweepGradient(100, 100, colors , positions); 

这里的问题是,BLUE的位置设置为当“1”,这并不意味着它将被定位在拉弧的结束,而是在年底圆弧的一部分。 为了解决这个问题,蓝色位置应该考虑到弧度的度数。所以,如果我画有X度的弧,位置将被设置像这样:

float[] positions = {0,Xf/360f}; 

所以,如果X是90,梯度将放置BLUE在圆的0.25:

enter image description here

+1

至少在Android 4.2中,给出的解决方案不起作用。在数组的末尾需要有一个值1。 类似这样的: int [] colors = {Color.RED,Color.BLUE,Color.BLUE}; float [] positions = {0,Xf/360f,1}; – 2013-05-11 07:19:04

+0

你知道为什么分辨率如此糟糕,如果角度很小?就像10度的弧度意味着只有3种颜色。你可以在你的屏幕截图中看到这些步骤 – 2016-04-05 15:37:23

9

添加到Yoav的解决方案。

在我的Galaxy Nexus 4.2股票Android上,提供的解决方案不起作用。如果数组不包含0.0f和1.0f,它似乎被忽略。

我最后的解决办法是:

int[] colors = {Color.RED, Color.BLUE, Color.RED}; 
float[] positions = {0, Xf/360f, 1}; 
1

五年后,但正确的做法是让0.749f与单独的线0.750f,简单的代码是这样的:

val colors = intArrayOf(0xffff0000.toInt(), 0xff0000ff.toInt(), 0xffff0000.toInt(), 0xffff0000.toInt()) 
    val positions = floatArrayOf(0.0f, 0.749f, 0.750f, 1.0f) 
+0

感谢张贴Kotlin – rundavidrun 2017-08-19 04:50:14