Skip to content

Instantly share code, notes, and snippets.

@policante
Last active October 17, 2018 20:16
Show Gist options
  • Save policante/d1c7ec5dcb7b3dc176be2b34d52b0c38 to your computer and use it in GitHub Desktop.
Save policante/d1c7ec5dcb7b3dc176be2b34d52b0c38 to your computer and use it in GitHub Desktop.
<declare-styleable name="ViewBox">
<attr name="backgroundColor" format="reference" />
<attr name="radius" format="reference|dimension" />
<attr name="paddingBox" format="reference|dimension" />
</declare-styleable>
public class ViewBox extends LinearLayout {
private float radiusCorner = 0f;
private int backgroundRes = -1;
private int paddingBox = 0;
public ViewBox(Context context) {
super(context);
init(null);
}
public ViewBox(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
public ViewBox(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init(attrs);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public ViewBox(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
init(attrs);
}
private void init(AttributeSet attrs) {
if (attrs != null) {
TypedArray typedArray = getContext().getTheme().obtainStyledAttributes(attrs, R.styleable.ViewBox, 0, 0);
try {
backgroundRes = typedArray.getResourceId(R.styleable.ViewBox_backgroundColor, -1);
radiusCorner = typedArray.getDimension(R.styleable.ViewBox_radius, getContext().getResources().getDimension(R.dimen.radius_box));
paddingBox = (int) typedArray.getDimension(R.styleable.ViewBox_paddingBox, getContext().getResources().getDimension(R.dimen.padding_box));
} finally {
typedArray.recycle();
}
}
if (backgroundRes == -1) {
backgroundRes = android.R.color.white;
}
setBackgroundResource(backgroundRes);
}
@Override
public void setBackgroundResource(int resid) {
backgroundRes = resid;
setBackground(null);
setBackground(ViewUtils.generateBackgroundWithShadow(this, resid, radiusCorner, R.color.shadowColor, R.dimen.elevation, Gravity.BOTTOM));
setPadding(this.paddingBox, this.paddingBox, this.paddingBox, this.paddingBox);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
}
public void setRadiusCorner(float radiusCorner) {
this.radiusCorner = radiusCorner;
setBackgroundResource(backgroundRes);
}
public void setPaddingBox(int paddingBox) {
this.paddingBox = paddingBox;
setBackgroundResource(backgroundRes);
}
}
public class ViewUtils {
public static Drawable generateBackgroundWithShadow(View view, @ColorRes int backgroundColor,
float cornerRadius,
@ColorRes int shadowColor,
@DimenRes int elevation,
int shadowGravity) {
int elevationValue = (int) view.getContext().getResources().getDimension(elevation);
int shadowColorValue = ContextCompat.getColor(view.getContext(), shadowColor);
int backgroundColorValue = ContextCompat.getColor(view.getContext(), backgroundColor);
float[] outerRadius = {cornerRadius, cornerRadius, cornerRadius,
cornerRadius, cornerRadius, cornerRadius, cornerRadius,
cornerRadius};
Rect shapeDrawablePadding = new Rect();
shapeDrawablePadding.left = elevationValue;
shapeDrawablePadding.right = elevationValue;
int DY;
switch (shadowGravity) {
case Gravity.CENTER:
shapeDrawablePadding.top = elevationValue;
shapeDrawablePadding.bottom = elevationValue;
DY = 0;
break;
case Gravity.TOP:
shapeDrawablePadding.top = elevationValue * 2;
shapeDrawablePadding.bottom = elevationValue;
DY = -1 * elevationValue / 3;
break;
default:
case Gravity.BOTTOM:
shapeDrawablePadding.top = elevationValue;
shapeDrawablePadding.bottom = elevationValue * 2;
DY = elevationValue / 3;
break;
}
ShapeDrawable shapeDrawable = new ShapeDrawable();
shapeDrawable.setPadding(shapeDrawablePadding);
shapeDrawable.getPaint().setColor(backgroundColorValue);
shapeDrawable.getPaint().setShadowLayer(cornerRadius / 3, 0, DY, shadowColorValue);
view.setLayerType(LAYER_TYPE_SOFTWARE, shapeDrawable.getPaint());
shapeDrawable.setShape(new RoundRectShape(outerRadius, null, null));
LayerDrawable drawable = new LayerDrawable(new Drawable[]{shapeDrawable});
drawable.setLayerInset(0, elevationValue, elevationValue * 2, elevationValue, elevationValue * 2);
return drawable;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment