I created an Android gradient drawable where the top and bottom are black and the center is transparent:
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<gradient
android:startColor="@android:color/black"
android:centerColor="@android:color/transparent"
android:endColor="@android:color/black"
android:angle="90"/>
</shape>
The rendered gradient looks like this:
As you can see, the black parts spread to most of the screen. I want the black to show only on a small portion of the top and bottom. Is there a way I can make the transparent center larger, or make the top and bottom black stripes smaller?
I tried playing around with some of the other XML attributes mentioned in the linked GradientDrawable
documentation, yet none of them seem to make and difference.
For an XML only solution, you can create a layer-list
with two separate gradient
objects.
The following code creates two overlapping gradient
objects and uses centerY
with centerColor
to offset the black section. Here, the centerY
attributes are set to 0.9
and 0.1
, so the black color is restricted to the top and bottom 10% of the view height.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape>
<gradient
android:angle="90"
android:centerColor="@android:color/transparent"
android:centerY="0.9"
android:endColor="@android:color/black"
android:startColor="@android:color/transparent" />
</shape>
</item>
<item>
<shape>
<gradient
android:angle="90"
android:centerColor="@android:color/transparent"
android:centerY="0.1"
android:endColor="@android:color/transparent"
android:startColor="@android:color/black" />
</shape>
</item>
</layer-list>
For API level 23 or higher, the following solution will also work, using android:height
. This solution can work even if you don't know the total height of your view, as long as you know how large you want the gradient to be.
This code creates two separate gradients, each with a height of 60sp
, and then uses android:gravity
to float the gradients to the top and bottom of the view.
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:height="60sp"
android:gravity="top">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="@android:color/black"
android:startColor="@android:color/transparent" />
</shape>
</item>
<item
android:height="65sp"
android:gravity="bottom">
<shape android:shape="rectangle">
<gradient
android:angle="90"
android:endColor="@android:color/transparent"
android:startColor="@android:color/black" />
</shape>
</item>
</layer-list>
Thank you @Luksprog for the code help, and @thenaoh for the start of the idea.
The above solutions work and it is nice that they are pure XML. If your gradient is showing with stripes, you may want to try a programmatic solution, like shown in @lelloman's answer, to create a smoother gradient.
Here is how it could be done with a custom Drawable
. You can tune the LinearGradient
as you want, and then set it as the view's background with view.setBackground(new CustomDrawable());
.
public class CustomDrawable extends Drawable {
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int[] colors;
private float[] positions;
public CustomDrawable() {
paint.setStyle(Paint.Style.FILL);
this.colors = new int[]{0xff000000, 0xffaaaaaa, 0xffffffff, 0xffaaaaaa, 0xff000000};
this.positions = new float[]{.0f, .2f, .5f, .8f, 1.f};
}
@Override
public void setBounds(int left, int top, int right, int bottom) {
super.setBounds(left, top, right, bottom);
LinearGradient linearGradient = new LinearGradient(left, top,left, bottom, colors, positions, Shader.TileMode.CLAMP);
paint.setShader(linearGradient);
}
@Override
public void draw(@NonNull Canvas canvas) {
canvas.drawRect(getBounds(), paint);
}
@Override
public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {
paint.setAlpha(alpha);
}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
paint.setColorFilter(colorFilter);
}
@Override
public int getOpacity() {
return PixelFormat.TRANSPARENT;
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With