Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SweepGradient change position of start and end color

I want to create a CircleView with gradient from bottom -> left -> top -> right.
So I using canvas with SweepGradient like this

protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    Paint paint = new Paint();

    int[] colors = {Color.GREEN, Color.RED};
    float[] positions = {0, 1};

    SweepGradient gradient = new SweepGradient(100, 100, colors, positions);
    paint.setShader(gradient);
    canvas.drawCircle(100, 100, 100, paint);
}

enter image description here

But the default order of this is right -> bottom -> left -> top but I want bottom -> left -> top -> right I have tried change the positions to

float[] positions = {0.25f, 1.25f};

but it only works in Preview of AndroidStudio, when I run in real device, it displays the result as same as positions = {0, 1}

How can I make SweepGradient gradient from bottom -> left -> top -> right like this

enter image description here

--- UPDATE --- We can use setLocalMatrix for SweepGradient like this for rotate the gradient

Matrix matrix = new Matrix();
matrix.setRotate(90, 100, 100);
gradient.setLocalMatrix(matrix);

enter image description here

like image 231
Linh Avatar asked Sep 07 '25 10:09

Linh


1 Answers

Rotate the canvas before drawing the circle.

public class CircleView extends View {
    private Paint paint;

    public CircleView(Context context) {
        super(context);
        init();
    }

    public CircleView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public CircleView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    public void init() {
        paint = new Paint();

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

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        canvas.save();
        canvas.rotate(90, 100, 100);
        canvas.drawCircle(100, 100, 100, paint);
        canvas.restore();
    }
}

Edit-1:
Alternative approach suggested by @pkskink is to use setLocalMatrix like below:

public void init() {      
    int[] colors = {Color.GREEN, Color.RED};
    float[] positions = {0, 1};

    Matrix matrix = new Matrix();
    matrix.postRotate(90, 100, 100);

    Shader gradient = new SweepGradient(100, 100, colors, positions);
    gradient.setLocalMatrix(matrix);

    paint = new Paint();
    paint.setShader(gradient);
}

@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawCircle(100, 100, 100, paint);
}
like image 124
blizzard Avatar answered Sep 09 '25 01:09

blizzard