25

ある色から別の色に徐々に変化する弧 (可変度数) を作成しようとしています。青から赤への例から:

ここに画像の説明を入力

これは私のコードです:

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);

しかし、その結果、アーク全体が同じ色でペイントされます。

編集:
さらに実験を重ねた結果、色の広がりは円弧の角度によって決まることがわかりました。小さな角度で円弧を描くと、最初の色だけが表示されます。角度が大きいほど、より多くの色が描画されます。角度が小さいと勾配がないように見えます。
ここに例があります。90、180、270、360 の 4 つの円弧を描いています。

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);

結果は次のとおりです。

ここに画像の説明を入力

赤が弧の始点にあり、青が終点にあり、その間のすべてが角度に関係なく均等に広がると予想していたので、これは驚くべきことです。
位置パラメーターを使用して手動で色の間隔を空けようとしましたが、結果は同じでした:

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

これを解決する方法はありますか?

4

4 に答える 4

32

これに対する解決策は、BLUE の位置を設定することです。これは次のように行われます。

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

ここでの問題は、BLUE の位置を '1' に設定すると、描画された円弧の端に配置されることを意味するのではなく、円弧が含まれる円の端に配置されることです。これを解決するには、BLUE の位置で円弧の度数を考慮する必要があります。したがって、X 度の円弧を描いている場合、位置は次のように設定されます。

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

したがって、X が 90 の場合、グラデーションは BLUE を円の 0.25 に配置します。

ここに画像の説明を入力

于 2012-01-29T16:03:41.300 に答える
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};
于 2013-05-11T07:50:20.483 に答える
0

を使用するSweepGradientと、位置を渡すことができnull(デフォルトのグラデーションが必要な場合)、グラデーションを回転させることもできますsetLocalMatrix

override fun onDraw(canvas: Canvas?) {
    super.onDraw(canvas)
    val centerX = width.toFloat() / 2
    val centerY = height.toFloat() / 2

    val paint = Paint()
    paint.isAntiAlias = true

    val colors = intArrayOf(Color.RED, Color.BLUE)
    val gradient = SweepGradient(centerX, centerY, colors, null) // null position
    val matrix = Matrix()
    matrix.postRotate(270f, centerX, centerY) // rotate
    gradient.setLocalMatrix(matrix)
    paint.shader = gradient

    val radius = 400f
    val oval = RectF(centerX - radius,centerY - radius,centerX + radius,centerY + radius)
    canvas?.drawArc(oval, 0f, 360f, false, paint)
}
于 2021-05-09T15:14:21.087 に答える