skip to Main Content

I came across Sweep Gradient on Android and was intrigued if it could give me a better control over the Color spacing and transitions. Did a quick search and found almost nothing about it!!

The only few references I found (and they do not meet the criteria of coming even close to explaining it properly or comprehensively) are listed below :

So thats almost about it. Others are similar or disparagingly brief.


Few conclusions I have drawn so far (and maybe are wrong) :

  • Sweep Gradient are mainly used for Rings
  • They are used for similar transactions as the Angular sweep (not sure about this one) which talks about transaction similar to sweep of a clock’s hand.
  • Very similar to Linear Gradients. The only thing I can think about for a difference between them is for the usage (like Rings).
  • Sweep deals with Center (again a strong reference towards the clock theory)

I know people may consider this as not really a technical question. But for me to work with Sweep Gradients or atleast know what they mean, the description has to come from somewhere. And please do provide the answers with some examples of usage of Sweep in cases other than Rings.

2

Answers


  1. The word gradient in this context (as in many graphics editors, including Photoshop) refers to a smooth transition between multiple colors, as opposed to using just a single color to fill an area.

    The Android API provides 3 different gradients: LinearGradient, RadialGradient and SweepGradient.

    These are all subclasses of Shader. You can set a Shader on a Paint object, and then draw any shape with that Paint. The shape will be filled with colors and transitions between them, according to the kind of the gradient.

    For example:

    output image of the code below

    This image can be produced with this code:

    Bitmap test = Bitmap.createBitmap(640, 200, Bitmap.Config.ARGB_8888);
    Canvas c = new Canvas(test);
    { // draw a dark gray background
        Paint backgroundPaint = new Paint();
        backgroundPaint.setARGB(255, 24, 24, 24);
        c.drawPaint(backgroundPaint);
    }
    Path heart = new Path();
    { // prepare a heart shape
        heart.moveTo(110, 175);
        heart.lineTo(10, 75);
        RectF leftCircle = new RectF(10, 25, 110, 125);
        heart.arcTo(leftCircle, 180, 180);
        RectF rightCircle = new RectF(110, 25, 210, 125);
        heart.arcTo(rightCircle, 180, 180);
        heart.close();
    }
    Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
    paint.setTextSize(18f);
    int[] colors = {
            0xFFFFFF88, // yellow
            0xFF0088FF, // blue
            0xFF000000, // black
            0xFFFFFF88  // yellow
    };
    float[] positions = {0.0f, 0.33f, 0.66f, 1.0f};
    { // draw the left heart
        SweepGradient sweepGradient;
        { // initialize the sweep gradient
            sweepGradient = new SweepGradient(50, 50, colors, positions);
            paint.setShader(sweepGradient);
        }
        c.drawPath(heart, paint);
        c.drawText("SweepGradient", 50, 190, paint);
    }
    { // draw the middle heart
        LinearGradient linearGradient;
        { // initialize a linear gradient
            linearGradient = new LinearGradient(250, 0, 350, 150, colors, positions, Shader.TileMode.CLAMP);
            paint.setShader(linearGradient);
        }
        heart.offset(210, 0); // move the heart shape to the middle
        c.drawPath(heart, paint);
        c.drawText("LinearGradient", 260, 190, paint);
    }
    { // draw the right heart
        RadialGradient radialGradient;
        { // initialize a linear gradient
            radialGradient = new RadialGradient(550, 50, 100, colors, positions, Shader.TileMode.CLAMP);
            paint.setShader(radialGradient);
        }
        heart.offset(210, 0); // move the heart shape to the right
        c.drawPath(heart, paint);
        c.drawText("RadialGradient", 470, 190, paint);
    }
    { // save the bitmap
        String filename = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "test.png";
        FileOutputStream out = null;
        try {
            out = new FileOutputStream(filename);
            test.compress(Bitmap.CompressFormat.PNG, 90, out);
        } catch (Exception e) {
        } finally {
            try {
                out.close();
            } catch (Exception e) {
            }
        }
    }
    
    • So the LinearGradient is Linear Gradient in Photoshop, RadialGradient is Radial Gradient, and SweepGradient is Angular Gradient, as described in your 3rd reference. I recommend trying these in an image editor first (all popular image editors have these tools), and you’ll quickly get the idea of how they work.

    • You can use these gradients in an XML drawable too (like in your 4th reference), with a limitation of using 3 colors maximum.

    • In a SweepGradient, when providing positions, the 0.0 point is at 3 o’clock, going clockwise (with 0.25 being at 6 o’clock, 0.5 at 9 o’clock, 0.75 at 12 o’clock, and 1.0 back at 3 o’clock).

    About your conclusions:

    • As you can see, any shape can be drawn with a SweepGradient, not just a ring. Even the labels are drawn with the gradients in the example above.
    • Yes, the clock’s hand analogy is spot on.
    • In usage, SweepGradient is very similar to LinearGradient, except you don’t need to provide a TileMode, because you cannot run outside of the bounds of your color list.
    • Yes, you need to provide the coordinates of the center point.

    I hope this clears it up.

    Login or Signup to reply.
  2. For xml drawable this can be specified with

    android:type="sweep"
    

    android:type can have values(case-sensitive): linear, radial or sweep

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search