How to add a stroke to ShapeDrawable - android

Hi
I want to create a shape drawable and fill it with gradient color with white stroke
here is my code
ShapeDrawable greenShape = new ShapeDrawable(new RectShape());
Shader shader1 = new LinearGradient(0, 0, 0, 50, new int[] {
0xFFBAF706, 0xFF4CD52F }, null, Shader.TileMode.CLAMP);
greenShape.getPaint().setShader(shader1);
greenShape.getPaint().setStrokeWidth(3);
greenShape.getPaint().setColor(Color.WHITE);
greenShape.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);`
The problem is the rectangle appears with gradient fill but without stroke

The ShapeDrawable does not allow you to easily draw a stroke around it.
If you really want then this would be a nice place to look at.
OR
You could use a GradientDrawable
GradientDrawable gd = new GradientDrawable();
gd.setColor(Color.RED);
gd.setCornerRadius(10);
gd.setStroke(2, Color.WHITE);
(PS: This is given as a comment in the same page!)

It looks like this person struggled with the same issue and the only way they found was to subclass the ShapeDrawable:
Trying to draw a button: how to set a stroke color and how to "align" a gradient to the bottom without knowing the height?

<stroke
android:width="2dp"
android:color="#808080" />
try it, it will work definitely

Change the style to greenShape.getPaint().setStyle(Paint.Style.STROKE)
and
greenShape.setShaderFactory(new ShapeDrawable.ShaderFactory() {
#Override
public Shader resize(int width, int height) {
return new LinearGradient(0, 0, 0, 0, Color.WHITE, Color.WHITE, Shader.TileMode.REPEAT);

Related

Android - How to apply gradient color to bitmap?

I need to apply dynamically a gradient color to a bitmap (it looks like a scratch with some transparent parts) that will be draw over another bitmap: this is the result i need.
This is my code:
Bitmap bitmapbackground = bitmaporiginal.copy(bitmaporiginal.getConfig(), true);
Bitmap bitmaptocolor = BitmapFactory.decodeResource(activity.getResources(), R.drawable.scratch);
LinearGradient gradient = new LinearGradient(0, 0, 0, bitmaptocolor.getHeight(), Color.parseColor("#D81B60"), Color.parseColor("#F48FB1"), Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(gradient);
Canvas canvas = new Canvas(bitmapbackground);
canvas.drawBitmap(bitmaptocolor, 0, 0, paint);
But in this way it does not apply the gradient color to the scratch (it remains always black). What am i doing wrong ?
Make sure bitmaptocolor.getHeight() is actually returning height.
Use hexadecimal equivalent for color.
LinearGradient gradient = new LinearGradient(0, 0, 0, bitmaptocolor.getHeight(), 0xD81B60, 0xD81B60, Shader.TileMode.CLAMP);

Programmatically setting Button Background Drawable Color

I have a drawable created beforehand which is a shape of rectangle but is fully transparent. Now I would like to assign this drawable to the Button in code but also set the Color of this drawable from transparent to some specific color like Orange etc.
I have already tried setting the same using some other posts like -
Drawable mDrawable = ContextCompat.getDrawable(this, R.drawable.square_transparent);
mDrawable.setColorFilter(
new PorterDuffColorFilter(
Color.Orange, Mode.SRC_IN)
);
but it doesn't work. When the activity renders the button ,it is still transparent only.
I also tried explicitly setting the mDrawable.setAlpha to 255 (fully opaque) before assigning the drawable to the button, but even that doesn't work.
Please suggest, if anyone has this working in some other fashion.
Use Mode.SRC instead of Mode.SRC_IN.
See the PorterDuff modes for more details.
Finally I got the end results using a 2 step solution -
I fixed the drawable from being a transparent one to pure white one with no opacity (it seems the color Filtering / tinting, works best on whites)
I also used the below lines of code to do the trick -
Drawable drawable = ResourcesCompat.getDrawable(context.getResources(), R.drawable.yourcustomshape, null);
drawable = DrawableCompat.wrap(drawable);
DrawableCompat.setTintList(drawable, ColorStateList.valueOf(Color.BLUE)); // Can be any color you need to color the shape
Using Two Methods You can Set background color and Border
This For Without background Color
public static GradientDrawable backgroundWithoutBorder(int color) {
GradientDrawable gdDefault = new GradientDrawable();
gdDefault.setColor(color);
gdDefault.setCornerRadii(new float[] { radius, radius, 0, 0, 0, 0,
radius, radius });
return gdDefault;
}
This For With background Color
public static GradientDrawable backgroundWithBorder(int bgcolor,
int brdcolor) {
GradientDrawable gdDefault = new GradientDrawable();
gdDefault.setColor(bgcolor);
gdDefault.setStroke(2, brdcolor);
gdDefault.setCornerRadii(new float[] { radius, radius, 0, 0, 0, 0,
radius, radius });
return gdDefault;
}

Programmatically add Gradient with solid color and stroke

Currently I am using this code to add color:
ShapeDrawable drawable = new ShapeDrawable(new OvalShape());
drawable.getPaint().setColor(color);
Now I need to apply some gradient colors to it along with stroke(like border with different color). I am setting this as background to button.
Here is what I am expecting, I need to do it programmatically.
Add a RadialGradient to your drawable like this:
Shader shader = new RadialGradient(x, y, radius, color0, color1, Shader.TileMode.REPEAT);
drawable.getPaint().setShader(shader);
Obviously, you can interchange LinearGradient, SweepGradient, and any of the parameters.
Here is how to add the stroke:
drawable.getPaint().setStrokeWidth(3);
drawable.getPaint().setColor(Color.WHITE);
drawable.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
Hmmm, I think I have to defer to #StinePike with the GradientDrawable:
GradientDrawable gd = new GradientDrawable();
gd.setColor(Color.RED);
gd.setCornerRadius(10);
gd.setStroke(2, Color.WHITE);
gd.setShape(GradientDrawable.OVAL);
use GradientDrawable to create gradient
or
you can see this answer

How can I draw a progressing ring with a gradient in Android?

I have a ShapeDrawable Object in my class in the form of an arc.
ShapeDrawable progressArc = new ShapeDrawable(new ArcShape(120, 12));
Now I would like to use a radial gradient effect on the color and also display just a ring instead of a filled arc. Does the Android SDK provide such a feature?
Currently using the below code, I get a gradient on the circle.
progressArc.setIntrinsicHeight(500);
progressArc.setIntrinsicWidth(500);
Shader shader1 = new LinearGradient(5, -5, 35, 0, new int[] { 0xFF33B5E5,0xFFFFFFFF }, null, Shader.TileMode.MIRROR);
progressArc.getPaint().setShader(shader1);
progressArc.getPaint().setStrokeWidth(1);
progressArc.getPaint().setColor(Color.RED);
progressArc.getPaint().setStyle(Paint.Style.FILL_AND_STROKE);
You can use a SweepGradient to get a radial gradient:
Shader s = new SweepGradient(0, 0, new int[] { 0xFF33B5E5,0xFFFFFFFF }, null);
//or if you only use two colors:
Shader s = new SweepGradient(0, 0, 0xFF33B5E5, 0xFFFFFFFF);
To avoid filling, just use the Paint.Style.STROKE style, with appropriate strokeWidth.

Trying to draw a button: how to set a stroke color and how to "align" a gradient to the bottom without knowing the height?

I am creating a button programmatically. It is rounded and has a gradient background, and works fine and looks nice, but I couldn't do two things I wanted:
Set a 1 pixel stroke with a given color. I tried getPaint().setStroke(), but couldn't figure how to set the stroke color. How should I do it?
Align the gradient to the bottom of the button, no matter what height it has. Is this possible?
For reference, this is the code I'm using:
Button btn = new Button(context);
btn.setPadding(7, 3, 7, 5);
btn.setTextColor(text_color);
// Create a gradient for the button. Height is hardcoded to 30 (I don't know the height beforehand).
// I wish I could set the gradient aligned to the bottom of the button.
final Shader shader = new LinearGradient(0, 0, 0, 30,
new int[] { color_1, color_2 },
null, Shader.TileMode.MIRROR);
float[] roundedCorner = new float[] { 5, 5, 5, 5, 5, 5, 5, 5 }
ShapeDrawable normal = new ShapeDrawable(new RoundRectShape(roundedCorner, null, null));
normal.getPaint().setShader(shader);
normal.setPadding(7, 3, 7, 5);
// Create a state list (I suppressed settings for pressed).
StateListDrawable state_list = new StateListDrawable();
state_list.addState(new int[] { }, normal);
btn.setBackgroundDrawable(state_list);
In terms of your first question, I struggled with this as well, and it doesn't look like there are any suitable methods within Drawables themselves (I was using ShapeDrawable) or the Paint class. However, I was able to extend ShapeDrawable and override the draw method, as below, to give the same result:
public class CustomBorderDrawable extends ShapeDrawable {
private Paint fillpaint, strokepaint;
private static final int WIDTH = 3;
public CustomBorderDrawable(Shape s) {
super(s);
fillpaint = this.getPaint();
strokepaint = new Paint(fillpaint);
strokepaint.setStyle(Paint.Style.STROKE);
strokepaint.setStrokeWidth(WIDTH);
strokepaint.setARGB(255, 0, 0, 0);
}
#Override
protected void onDraw(Shape shape, Canvas canvas, Paint fillpaint) {
shape.draw(canvas, fillpaint);
shape.draw(canvas, strokepaint);
}
public void setFillColour(int c){
fillpaint.setColor(c);
}
}
You can use a GradientDrawable with setStroke(3, Color.WHITE) method. To make rounded corners, use this:
setShape(GradientDrawable.RECTANGLE);
setCornerRadii(new float[]{2,2,2,2,2,2,2,2});
Try this....in drawable make a new xml file and set it where you want it..!
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle" >
<solid android:color="#e1e1e1" />
<stroke
android:width="2dp"
android:color="#808080" />
<corners android:radius="10dp" />
<padding
android:bottom="5dp"
android:left="5dp"
android:right="5dp"
android:top="5dp" />
</shape>

Categories

Resources