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 nothin
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:
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:
SweepGradient
, not just a ring. Even the labels are drawn with the gradients in the example above.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.I hope this clears it up.