content: package com.reactnativefastshadow;
  
  import android.content.Context;
  import android.graphics.Canvas;
  import android.graphics.Rect;
  import android.graphics.drawable.Drawable;
  
  
  import com.facebook.react.uimanager.PixelUtil;
  import com.facebook.react.views.view.ReactViewGroup;
  
  public class FastShadowView extends ReactViewGroup {
    private static ShadowCache shadowCache = new ShadowCache();
  
    private Shadow shadow;
    private int color = 0xff000000;
    private float opacity = 0;
    private float radius = 0;
    private float offsetX = 0;
    private float offsetY = -3;
    private float[] cornerRadii = {0, 0, 0, 0}; // in clockwise order: tl, tr, br, bl
  
    public FastShadowView(Context context) {
      super(context);
    }
  
    public void setColor(int color) {
      this.color = color;
      this.invalidate();
    }
  
    public void setOpacity(float opacity) {
      this.opacity = opacity;
  
      // We need to call this, as draw() is not called by default on ViewGroup
      this.setWillNotDraw(opacity <= 0);
      this.invalidate();
    }
  
    public void setRadius(float radius) {
      this.radius = radius;
      this.invalidate();
    }
  
    public void setOffset(float offsetX, float offsetY) {
      this.offsetX = offsetX;
      this.offsetY = offsetY;
      this.invalidate();
    }
  
    public void resetOffset() {
      setOffset(0, -3);
    }
  
    public void setCornerRadii(float[] cornerRadii) {
      this.cornerRadii = cornerRadii;
      this.invalidate();
    }
  
    public void releaseShadow() {
      shadowCache.releaseShadow(shadow);
      shadow = null;
    }
  
    @Override
    public void draw(Canvas canvas) {
      // We override draw() and not onDraw() as we want to draw
      // our shadow behind the background drawable of the View.
  
      if (opacity > 0) {
        int width = dp(getWidth());
        int height = dp(getHeight());
  
        Shadow prevShadow = shadow;
        shadow = shadowCache.getOrCreateShadow(getContext(), width, height, cornerRadii, radius);
        shadowCache.releaseShadow(prevShadow);
  
        if (shadow != null) {
          Drawable drawable = shadow.getDrawable();
          drawable.setBounds(new Rect(
            px(-radius + offsetX),
            px(-radius + offsetY),
            getWidth() + px(radius + offsetX),
            getHeight() + px(radius + offsetY)
          ));
          drawable.setAlpha(Math.round(opacity * 255));
          drawable.setTint(color);
          drawable.draw(canvas);
        }
      }
  
      super.draw(canvas);
    }
  
    static int dp(float px) {
      return Math.round(PixelUtil.toDIPFromPixel(px));
    }
  
    static int px(float dp) {
      return Math.round(PixelUtil.toPixelFromDIP(dp));
    }
  }
  