Skip to content

Instantly share code, notes, and snippets.

@benvium
Created September 3, 2014 20:41
Show Gist options
  • Select an option

  • Save benvium/c67206c2d65c60efeb67 to your computer and use it in GitHub Desktop.

Select an option

Save benvium/c67206c2d65c60efeb67 to your computer and use it in GitHub Desktop.
Programatically create a clickable, disableable, drawable with rounded corners, where the color doesn't have to be known at compile-time. If your color is fixed, then it's easy to use XML to do this, but if the color is completely dynamic this is a good option.
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.util.StateSet;
import android.view.View;
/**
* Creates a drawable with normal, pressed, and disabled states with rounded corners,
* using a color you pass in using code.
*
* The normal state is based on the color you pass in. Easy to adapt to other color schemes etc.
* If your color is fixed, then it's easy to use XML to do this, but if the color
* is completely dynamic this is a good option.
*
* Ben Clayton
* @benclayton
*
* github.com/benvium
*/
public class DynamicColorRoundedRectDrawable extends StateListDrawable {
public DynamicColorRoundedRectDrawable(Context ctx, int color) {
int lightGrey = ctx.getResources().getColor(R.color.light_grey);
int disabled_grey_button = ctx.getResources().getColor(R.color.disabled_grey_button);
addState(new int[]{android.R.attr.state_pressed}, new RRDrawable(ctx, lightGrey));
addState(new int[]{-android.R.attr.state_enabled}, new RRDrawable(ctx, disabled_grey_button));
addState(StateSet.WILD_CARD, new RRDrawable(ctx, color));
}
/**
* Helper class to get around the annoying setDrawable / setBackgroundDrawable deprecated issues for API 14 / 16
* @param view View to apply this as the background to
*/
public void setAsBackground(View view) {
if(android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.JELLY_BEAN) {
//noinspection deprecation
view.setBackgroundDrawable(this);
} else {
view.setBackground(this);
}
}
/**
* Inner class that holds a single state of the drawable.
*/
public static class RRDrawable extends Drawable {
private final Context ctx;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
public RRDrawable(Context ctx, int color) {
this.ctx = ctx;
paint.setColor(color);
paint.setStyle(Paint.Style.FILL);
}
@Override
public void draw(Canvas canvas) {
int radius = PixelUtils.dpToPixels(ctx, 5);
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;
}
}
}
View view = findViewById(R.id.test);
// If you're using API<16 use can use a convenience method to get around the deprecated setBackgroundDrawable call.
new DynamicColorRoundedRectDrawable(this, getResources().getColor(R.color.skin)).setAsBackground(view);
// Or for API>=16..
view.setBackground( new DynamicColorRoundedRectDrawable(this, getResources().getColor(R.color.skin)) );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment