Android - 如何绘制基于弧的渐变

Yoa*_*oav 23 graphics android 2d geometric-arc

我正在尝试创建一个逐渐从一种颜色到另一种颜色的弧(可变度数).例如从蓝色到红色:

在此输入图像描述

这是我的代码:

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);
Run Code Online (Sandbox Code Playgroud)

但结果是整个弧线都涂上了相同的颜色.

编辑:
经过更多的实验,我发现颜色的扩散是由弧的角度决定的.如果我绘制一个小角度的圆弧,则只显示第一种颜色.角度越大,绘制的颜色越多.如果角度很小,似乎没有渐变.
这是一个例子.我画了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);
Run Code Online (Sandbox Code Playgroud)

这是结果:

在此输入图像描述

这是令人惊讶的,因为我希望RED在弧线的起点,最后的BLUE和它们之间的均匀分布,无论角度如何.
我尝试使用position参数手动分隔颜色,但结果是相同的:

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

不知道怎么解决这个问题?

Yoa*_*oav 30

解决方案是设置BLUE的位置.这样做是这样的:

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

这里的问题是,当将BLUE的位置设置为"1"时,这并不意味着它将位于绘制弧的末端,而是位于弧所属的圆的末端.要解决这个问题,蓝色位置应考虑弧度中的度数.因此,如果我用X度绘制弧,则位置将如下设置:

float[] positions = {0,Xf/360f};
Run Code Online (Sandbox Code Playgroud)

因此,如果X为90,则渐变将BLUE置于圆的0.25处:

在此输入图像描述

  • 至少在Android 4.2上,给出的解决方案不起作用.数组末尾需要值为1.像这样:int [] colors = {Color.RED,Color.BLUE,Color.BLUE}; float [] positions = {0,Xf/360f,1}; (2认同)

Tom*_*ney 11

添加到Yoav的解决方案.

在我的Galaxy Nexus 4.2股票Android上,给出的解决方案不起作用.

如果数组不包含0.0f和1.0f,则它似乎被忽略.

我的最终解决方案是:

int[] colors = {Color.RED, Color.BLUE, Color.RED}; 
float[] positions = {0, Xf/360f, 1};
Run Code Online (Sandbox Code Playgroud)