I am looking to draw a gradient like this using Android's Canvas
:
In the horizontal direction there is a gradient of two colors (red and blue). Then in the vertical direction there is a gradient of transparency (allowing the red and blue to show) to nothing (the absence of all color?).
I found this link on SO here which is close to what I want. But I cannot figure out how to make the bottom transparent.
How can this be accomplished in Android?
Those sort of "custom" gradients can sometimes be pretty annoying.
To make it as painless as you can, you could use specially prepared drawable resource.
There are two main ways you can accomplish that with a drawable:
- Use two linear gradients
- Use two radial gradients
The first approach could be implemented like this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="315"
android:centerColor="#4DFC0A00"
android:endColor="#00FC0A00"
android:startColor="#FC0A00" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="225"
android:centerColor="#4D5E17FD"
android:endColor="#005E17FD"
android:startColor="#5E17FD" />
</shape>
</item>
</layer-list>
And it would look like this (presented on white background):
You could still twitch centerX
and centerY
values for those gradients (defaults are 0.5
)
The second approach could be implemented like this:
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:centerX="0"
android:centerY="0"
android:gradientRadius="@dimen/gradient_width"
android:endColor="#00FC0A00"
android:centerColor="#80FC0A00"
android:startColor="#FC0A00"
android:type="radial" />
</shape>
</item>
<item>
<shape>
<gradient
android:centerX="1"
android:centerY="0"
android:gradientRadius="@dimen/gradient_width"
android:endColor="#005E17FD"
android:centerColor="#805E17FD"
android:startColor="#5E17FD"
android:type="radial" />
</shape>
</item>
</layer-list>
And it would look like this (presented on white background):
The one downside of the second approach is that you need to know your gradient width to set the gradientRadius
.
You can also not set the gradientRadius
to the full width, but like a 75% of it. It will give it a nice overlap but not too much.
Here's how to draw it in Skia using C++.
The equivalent in Java on Android should be very similar.
SkColor colors[] = { SK_ColorRED, SK_ColorBLUE };
SkPoint horz[] = { { 0, 0 }, { 256, 0 } };
SkPaint paint;
paint.setShader(SkGradientShader::MakeLinear(horz, colors, nullptr, 2,
SkShader::kClamp_TileMode));
canvas->drawPaint(paint);
paint.setBlendMode(SkBlendMode::kDstIn);
SkColor alphas[] = { SK_ColorBLACK, SK_ColorTRANSPARENT };
SkPoint vert[] = { { 0, 0 }, { 0, 256 } };
paint.setShader(SkGradientShader::MakeLinear(vert, alphas, nullptr, 2,
SkShader::kClamp_TileMode));
canvas->drawPaint(paint);
gradient with fade