This is the prototype of my solution:
I created a custom FrameLayout method and override onDraw . Here's what it looks like:

I will add comments and a description of how this works, soon!
public class CurvedFrameLayout extends FrameLayout { private Paint paint; private Path path; private int width; private int height; private float leftCurvePosition = 0.5f; private float topCurvePosition = 0.5f; private float rightCurvePosition = 0.5f; private float bottomCurvePosition = 0.5f; private int minimumCurve = 50; private int maximumCurve = 100; private int minimumLeftCurve = minimumCurve; private int minimumTopCurve = minimumCurve; private int minimumRightCurve = minimumCurve; private int minimumBottomCurve = minimumCurve; private int maximumLeftCurve = maximumCurve; private int maximumTopCurve = maximumCurve; private int maximumRightCurve = maximumCurve; private int maximumBottomCurve = maximumCurve; private float leftCurveOffset = 0f; private float topCurveOffset = 0f; private float rightCurveOffset = 0f; private float bottomCurveOffset = 0f; private int curveRadius = 150; private float elevation = 4f; private float cornerRadius = 50f; private float margin = elevation; private int color = Color.LTGRAY; public CurvedFrameLayout(Context context) { super(context); init(context, null); } public CurvedFrameLayout(Context context, AttributeSet attrs) { super(context, attrs); init(context, attrs); } public CurvedFrameLayout(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(context, attrs); } private void init(Context context, AttributeSet attrs) { if (attrs != null) { TypedArray a = context.getTheme().obtainStyledAttributes( attrs, R.styleable.CurvedFrameLayout, 0, 0); try { leftCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_leftCurvePosition, 0.5f); topCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_topCurvePosition, 0.5f); rightCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_rightCurvePosition, 0.5f); bottomCurvePosition = a.getFloat(R.styleable.CurvedFrameLayout_bottomCurvePosition, 0.5f); minimumCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumCurve, 50); maximumCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumCurve, 100); minimumLeftCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumLeftCurve, 50); minimumTopCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumTopCurve, 50); minimumRightCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumRightCurve, 50); minimumBottomCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_minimumBottomCurve, 50); maximumLeftCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumLeftCurve, 100); maximumTopCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumTopCurve, 100); maximumRightCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumRightCurve, 100); maximumBottomCurve = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_maximumBottomCurve, 100); leftCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_leftCurveOffset, 0f); topCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_topCurveOffset, 0f); rightCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_rightCurveOffset, 0f); bottomCurveOffset = a.getFloat(R.styleable.CurvedFrameLayout_bottomCurveOffset, 0f); curveRadius = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_curveRadius, 150); cornerRadius = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_cornerRadius, 50); elevation = a.getDimensionPixelSize(R.styleable.CurvedFrameLayout_elevation, 0); margin = elevation; color = a.getColor(R.styleable.CurvedFrameLayout_color, Color.LTGRAY); } finally { a.recycle(); } } setWillNotDraw(false); paint = new Paint();
The code is not perfect at the moment, but as soon as I improve this code, I will update the answer.