11

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:

  1. 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?
  2. 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);
moraes
  • 13,213
  • 7
  • 45
  • 59

3 Answers3

22

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);
    }
}
Stev_k
  • 2,118
  • 3
  • 22
  • 36
  • This almost works, but the stroke is clipped. This link has more details: http://www.betaful.com/2012/01/programmatic-shapes-in-android/ – mxcl Feb 23 '12 at 22:55
  • 1
    The above link is broken. This is the updated link: http://betaful.com/post/82668809883/programmatic-shapes-in-android – Shams Shafiq Nov 04 '15 at 21:40
  • @ShamsShafiq,@Stev_k@moraes, i had tried to use your this as well as betauful.com answer to create border with corner radius programatically... and it works very well but it also creates an edge outside the view. The view i got is present at the link https://drive.google.com/file/d/0BwkVxZWl7VcETlIySV82NC1sV2s/view?usp=sharing, so please help me in remove the greying edge.. – Reprator Feb 18 '16 at 11:59
8

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});
Paŭlo Ebermann
  • 73,284
  • 20
  • 146
  • 210
garmax1
  • 898
  • 1
  • 10
  • 21
1

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>
jigar
  • 1,571
  • 6
  • 23
  • 46