与剪切的背景在边缘/习惯背景形状

时间:2016-09-21 13:35:32

标签: android

我必须使用ViewPager创建Fragments,主要问题是,每个片段的背景都需要在背景中进行切割。在拖动时切入应该扩大。你有任何想法怎么做吗?

看起来应该是这样的:

enter image description here enter image description here

2 个答案:

答案 0 :(得分:2)

你可以在git中引用流动抽屉

链接:https://github.com/mxn21/FlowingDrawer

在此示例中,他们使用“LeftDrawerLayout”自定义类来处理此效果,其属性由FlowingView设置。

使用此选项创建自定义类。

答案 1 :(得分:0)

这是我的解决方案的原型:

我创建了自定义FrameLayout并覆盖onDraw方法。这就是它的样子:

enter image description here

  

我会很快添加评论和说明,它是如何工作的!

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();
    }
}

目前,代码并不完美,但只要我改进此代码,我就会更新答案。