Подтвердить что ты не робот

Android - Как нарисовать градиент на основе дуги

Я пытаюсь создать дугу (переменное число градусов), которая постепенно переходит от одного цвета к другому. Пример от синего до красного:

enter image description here

Это мой код:

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

Но результат состоит в том, что вся дуга окрашена в один цвет.

Edit:
После дополнительных экспериментов выяснилось, что разброс цветов определяется углом дуги. Если я рисую дугу с небольшим углом, отображается только первый цвет. Чем больше угол, тем больше рисунков. Если угол мал, кажется, что градиента нет.
Вот пример. Я рисую 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 будет в начале дуги, BLUE в конце и enything между тем, чтобы распределяться равномерно независимо от угла.
Я попытался выделить цвета вручную, используя параметр position, но результаты были одинаковыми:

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

Любая идея, как это решить?

4b9b3361

Ответ 1

Решение для этого - установить положение 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

Ответ 2

Чтобы добавить к решению Yoav.

В моем Android-приложении Galaxy Nexus 4.2 данное решение не работает.

Если массив не содержит 0.0f и 1.0f, он, кажется, игнорируется.

Моим окончательным решением было:

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

Ответ 3

пять лет спустя, но правильный путь составляет 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)