2

I have a drawable that will change colors sometimes, but it must ALWAYS have rounded corners. It's for a UI library, so I can't know what colors will it have. XML is not an option, I have to achieve this with pure java.

Is there a way to achieve this programatically WITHOUT using XML?

Charlie-Blake
  • 10,832
  • 13
  • 55
  • 90

3 Answers3

2

Create a custom Drawable (i.e. extend Drawable) and in its onDraw use Canvas.drawRoundRect(RectF rect, float rx, float ry, Paint paint), setting the Paint to the desired colour.

nmw
  • 6,664
  • 3
  • 31
  • 32
  • Yeah, but I'll need to know the dimensions. I want to get the same results as if I did it with XML. – Charlie-Blake Oct 09 '12 at 11:42
  • A Drawable gets its dimensions via setBounds, which is called automatically if the Drawable is set to a background of a View. – nmw Oct 09 '12 at 13:04
1

If you draw the drawable by yourself, you could set a clip path with Canvas.clipPath. The path would consist of one or more rectangles and some circles, which clip the rounded corners. You probably have to play around with the arrangement of the path components until you get the desired output.

henrik
  • 708
  • 7
  • 14
1

Based on the answer from @nmw, here's some code that works for this:

public class RRDrawable extends Drawable {
    private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);

    public RRDrawable(int color) {
        paint.setColor(color);
        paint.setStyle(Paint.Style.FILL);
    }

    @Override
    public void draw(Canvas canvas) {
        int radius = 10; // note this is actual pixels
        canvas.drawRoundRect(new RectF(0,0,canvas.getWidth(), canvas.getHeight()), radius, radius,  paint);
    }

    @Override
    public void setAlpha(int i) {
        //.. not supported
    }

    @Override
    public void setColorFilter(ColorFilter colorFilter) {
        //.. not supported
    }

    @Override
    public int getOpacity() {
        return 1;
    }
}

EDIT: added anti-aliasing to the edges.

(source)

Ben Clayton
  • 80,996
  • 26
  • 120
  • 129