Edge Split Background / Custom Background Shape

I need to create a ViewPager using Fragments , and the main problem is that each background of the fragment must have a cut at the edge in the background. The contraction should expand as you drag. Do you have any idea how to do this?

It should look like this:

enter image description here enter image description here

+6
source share
2 answers

U can reference Flowing Drawer in git

Link: https://github.com/mxn21/FlowingDrawer

In this example, they use the "LeftDrawerLayout" special class to handle this effect, and its property is set by FlowingView.

Use this to create a custom class.

+2
source

This is the prototype of my solution:

I created a custom FrameLayout method and override onDraw . Here's what it looks like:

enter image description here

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(); //setLayerType(LAYER_TYPE_SOFTWARE, paint); paint.setColor(color); paint.setShadowLayer(elevation, 0f, 0f, Color.LTGRAY); path = new Path(); } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); drawLayout(canvas); } private void drawLayout(Canvas canvas) { float cornerRadiusMargin = cornerRadius + margin; float widthMinusMargin = width - margin; float widthMinusMarginMinusCornerR = widthMinusMargin - cornerRadius; float heightMinusMargin = height - margin; float heightMinusMarginMinusCornerR = heightMinusMargin - cornerRadius; //Top-left corner path.reset(); path.moveTo(margin, cornerRadiusMargin); path.quadTo(margin, margin, cornerRadiusMargin, margin); //Top line drawTopEdge(cornerRadiusMargin, margin, widthMinusMarginMinusCornerR, margin); //Top-right corner path.quadTo(widthMinusMargin, margin, widthMinusMargin, cornerRadiusMargin); //Right line drawRightEdge(widthMinusMargin, cornerRadiusMargin, widthMinusMargin, heightMinusMarginMinusCornerR); //Bottom-right corner path.quadTo(widthMinusMargin, heightMinusMargin, widthMinusMarginMinusCornerR, heightMinusMargin); //Bottom line path.lineTo(cornerRadiusMargin, heightMinusMargin); //Bottom-left corner path.quadTo(margin, heightMinusMargin, margin, heightMinusMarginMinusCornerR); //Left line drawLeftEdge(margin, heightMinusMarginMinusCornerR, margin, cornerRadiusMargin); canvas.drawPath(path, paint); canvas.clipPath(path, Region.Op.REPLACE); } private void drawTopEdge(float x1, float y1, float x2, float y2) { float curveCenterX = (x1 + x2) * topCurvePosition; float curveDeltaY = positionForOffset(minimumTopCurve, maximumTopCurve, topCurveOffset); int curveX = curveRadius / 2; path.lineTo(curveCenterX - curveRadius, y1); path.rCubicTo(curveX, 0, curveX, curveDeltaY, curveRadius, curveDeltaY); path.rCubicTo(curveX, 0, curveX, -curveDeltaY, curveRadius, -curveDeltaY); path.lineTo(x2, y2); } private void drawRightEdge(float x1, float y1, float x2, float y2) { float curveCenterY = (y1 + y2) * rightCurvePosition; float curveDeltaX = positionForOffset(minimumRightCurve, maximumRightCurve, rightCurveOffset); path.lineTo(x1, curveCenterY - curveRadius); int curveY = curveRadius / 2; path.rCubicTo(0, curveY, -curveDeltaX, curveY, -curveDeltaX, curveRadius); path.rCubicTo(0, curveY, curveDeltaX, curveY, curveDeltaX, curveRadius); path.lineTo(x2, y2); } private void drawLeftEdge(float x1, float y1, float x2, float y2) { float curveCenterY = (y1 + y2) * leftCurvePosition; float curveDeltaX = positionForOffset(minimumLeftCurve, maximumLeftCurve, leftCurveOffset); path.lineTo(x1, curveCenterY + curveRadius); int curveY = -curveRadius / 2; path.rCubicTo(0, curveY, curveDeltaX, curveY, curveDeltaX, -curveRadius); path.rCubicTo(0, curveY, -curveDeltaX, curveY, -curveDeltaX, -curveRadius); path.lineTo(x2, y2); } private float positionForOffset(float start, float end, float offset) { return start + (end - start) * offset; } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); width = w; height = h; } public void setLeftCurveOffset(float leftCurveOffset) { this.leftCurveOffset = leftCurveOffset; invalidate(); } public void setRightCurveOffset(float rightCurveOffset) { this.rightCurveOffset = rightCurveOffset; invalidate(); } } 

The code is not perfect at the moment, but as soon as I improve this code, I will update the answer.

0
source

All Articles