如何反转弧形底部导航?

时间:2018-12-06 18:57:51

标签: android canvas path

我找到了一个https://github.com/androidtutorialonline/CurvedBottomNavigationView库,该库用画布绘制了一条曲线。 我想反转曲线,以使曲线不会从顶部开始。 曲线应从底部到顶部。但是我现在真的不知道如何将其反转。我从2个小时开始尝试,我不知道该如何绘制立方体。

它看起来像这样:

enter image description here

但是我希望它看起来像这样, 它只应更改此图中的曲线。 而且不要像我所做的那样旋转整个过程以使您清楚。 只能按照以下屏幕截图所示绘制曲线:

enter image description here

有密码

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.util.AttributeSet;

public class Test extends BottomNavigationView {
    private Path mPath;
    private Paint mPaint;


    /** the CURVE_CIRCLE_RADIUS represent the radius of the fab button */
    public final int CURVE_CIRCLE_RADIUS = 256 / 3;
    // the coordinates of the first curve
    public Point mFirstCurveStartPoint = new Point();
    public Point mFirstCurveEndPoint = new Point();
    public Point mFirstCurveControlPoint2 = new Point();
    public Point mFirstCurveControlPoint1 = new Point();

    //the coordinates of the second curve
    @SuppressWarnings("FieldCanBeLocal")
    public Point mSecondCurveStartPoint = new Point();
    public Point mSecondCurveEndPoint = new Point();
    public Point mSecondCurveControlPoint1 = new Point();
    public Point mSecondCurveControlPoint2 = new Point();
    public int mNavigationBarWidth;
    public int mNavigationBarHeight;

    public Test(Context context) {
        super(context);
        init();
    }

    public Test(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }

    public Test(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        mPath = new Path();
        mPaint = new Paint();
        mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
        mPaint.setColor(Color.WHITE);
        setBackgroundColor(Color.TRANSPARENT);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);

    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        // get width and height of navigation bar
        // Navigation bar bounds (width & height)
         mNavigationBarWidth = getWidth();
         mNavigationBarHeight = getHeight();
        // the coordinates (x,y) of the start point before curve
        mFirstCurveStartPoint.set((mNavigationBarWidth / 2) - (CURVE_CIRCLE_RADIUS * 2) - (CURVE_CIRCLE_RADIUS / 3), 0);
        // the coordinates (x,y) of the end point after curve
        mFirstCurveEndPoint.set(mNavigationBarWidth / 2, CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4));
        // same thing for the second curve
        mSecondCurveStartPoint = mFirstCurveEndPoint;
        mSecondCurveEndPoint.set((mNavigationBarWidth / 2) + (CURVE_CIRCLE_RADIUS * 2) + (CURVE_CIRCLE_RADIUS / 3), 0);

        // the coordinates (x,y)  of the 1st control point on a cubic curve
        mFirstCurveControlPoint1.set(mFirstCurveStartPoint.x + CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4), mFirstCurveStartPoint.y);
        // the coordinates (x,y)  of the 2nd control point on a cubic curve
        mFirstCurveControlPoint2.set(mFirstCurveEndPoint.x - (CURVE_CIRCLE_RADIUS * 2) + CURVE_CIRCLE_RADIUS, mFirstCurveEndPoint.y);

        mSecondCurveControlPoint1.set(mSecondCurveStartPoint.x + (CURVE_CIRCLE_RADIUS * 2) - CURVE_CIRCLE_RADIUS, mSecondCurveStartPoint.y);
        mSecondCurveControlPoint2.set(mSecondCurveEndPoint.x - (CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4)), mSecondCurveEndPoint.y);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mPath.reset();
        mPath.moveTo(0, 0);
        mPath.lineTo(mFirstCurveStartPoint.x, mFirstCurveStartPoint.y);

        mPath.cubicTo(mFirstCurveControlPoint1.x, mFirstCurveControlPoint1.y,
                mFirstCurveControlPoint2.x, mFirstCurveControlPoint2.y,
                mFirstCurveEndPoint.x, mFirstCurveEndPoint.y);

        mPath.cubicTo(mSecondCurveControlPoint1.x, mSecondCurveControlPoint1.y,
                mSecondCurveControlPoint2.x, mSecondCurveControlPoint2.y,
                mSecondCurveEndPoint.x, mSecondCurveEndPoint.y);

        mPath.lineTo(mNavigationBarWidth, 0);
        mPath.lineTo(mNavigationBarWidth, mNavigationBarHeight);
        mPath.lineTo(0, mNavigationBarHeight);
        mPath.close();

        canvas.drawPath(mPath, mPaint);
    }
}

1 个答案:

答案 0 :(得分:1)

由于要在x轴上镜像给定曲线,因此必须更改所有点的y坐标。例子:

  • 0变为 navigationbarHeight
  • navigationbarHeight 变为0
  • RADIUS变为 navigationbarHeight -RADIUS

我引入了其他变量,以便能够在同一View中绘制两条曲线:

private Path mOtherPath;
private Paint mOtherPaint;


// the coordinates of the first "inverted" curve
public Point mFirstOtherCurveStartPoint = new Point();
public Point mFirstOtherCurveEndPoint = new Point();
public Point mFirstOtherCurveControlPoint2 = new Point();
public Point mFirstOtherCurveControlPoint1 = new Point();

//the coordinates of the second "inverted" curve
@SuppressWarnings("FieldCanBeLocal")
public Point mSecondOtherCurveStartPoint = new Point();
public Point mSecondOtherCurveEndPoint = new Point();
public Point mSecondOtherCurveControlPoint1 = new Point();
public Point mSecondOtherCurveControlPoint2 = new Point();

初始化Path中的Paintinit()

private void init() {
    mPath = new Path();
    mPaint = new Paint();
    mPaint.setStyle(Paint.Style.FILL_AND_STROKE);
    mPaint.setColor(Color.LTGRAY);

    mOtherPath = new Path();
    mOtherPaint = new Paint();
    mOtherPaint.setStyle(Paint.Style.STROKE);
    mOtherPaint.setStrokeWidth(8f);
    mOtherPaint.setColor(Color.RED);

    setBackgroundColor(Color.TRANSPARENT);
}

onSizeChanged()

中的新变量设置值
// ... last lines of the given curve ...
mSecondCurveControlPoint1.set(mSecondCurveStartPoint.x + (CURVE_CIRCLE_RADIUS * 2) - CURVE_CIRCLE_RADIUS, mSecondCurveStartPoint.y);
mSecondCurveControlPoint2.set(mSecondCurveEndPoint.x - (CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4)), mSecondCurveEndPoint.y);

// and now once more for the "inverted" curve...
//

// the coordinates (x,y) of the start point before curve
mFirstOtherCurveStartPoint.set((mNavigationBarWidth / 2) - (CURVE_CIRCLE_RADIUS * 2) - (CURVE_CIRCLE_RADIUS / 3), mNavigationBarHeight);
// the coordinates (x,y) of the end point after curve
mFirstOtherCurveEndPoint.set(mNavigationBarWidth / 2, mNavigationBarHeight - (CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4) ) );
// same thing for the second curve
mSecondOtherCurveStartPoint = mFirstOtherCurveEndPoint;
mSecondOtherCurveEndPoint.set((mNavigationBarWidth / 2) + (CURVE_CIRCLE_RADIUS * 2) + (CURVE_CIRCLE_RADIUS / 3), mNavigationBarHeight);

// the coordinates (x,y)  of the 1st control point on a cubic curve
mFirstOtherCurveControlPoint1.set(mFirstOtherCurveStartPoint.x + CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4), mFirstOtherCurveStartPoint.y);
// the coordinates (x,y)  of the 2nd control point on a cubic curve
mFirstOtherCurveControlPoint2.set(mFirstOtherCurveEndPoint.x - (CURVE_CIRCLE_RADIUS * 2) + CURVE_CIRCLE_RADIUS, mFirstOtherCurveEndPoint.y);

mSecondOtherCurveControlPoint1.set(mSecondOtherCurveStartPoint.x + (CURVE_CIRCLE_RADIUS * 2) - CURVE_CIRCLE_RADIUS, mSecondOtherCurveStartPoint.y);
mSecondOtherCurveControlPoint2.set(mSecondOtherCurveEndPoint.x - (CURVE_CIRCLE_RADIUS + (CURVE_CIRCLE_RADIUS / 4)), mSecondOtherCurveEndPoint.y);

最后,将onDraw()

中的所有内容修补在一起
// ... last line of drawing the "normal" curve ...
canvas.drawPath(mPath, mPaint);

// now we draw the mirrored curve:
mOtherPath.reset();
mOtherPath.moveTo(0, mNavigationBarHeight);
mOtherPath.lineTo(mFirstOtherCurveStartPoint.x, mFirstOtherCurveStartPoint.y);
mOtherPath.cubicTo(mFirstOtherCurveControlPoint1.x, mFirstOtherCurveControlPoint1.y,
        mFirstOtherCurveControlPoint2.x, mFirstOtherCurveControlPoint2.y,
        mFirstOtherCurveEndPoint.x, mFirstOtherCurveEndPoint.y);

mOtherPath.cubicTo(mSecondOtherCurveControlPoint1.x, mSecondOtherCurveControlPoint1.y,
        mSecondOtherCurveControlPoint2.x, mSecondOtherCurveControlPoint2.y,
        mSecondOtherCurveEndPoint.x, mSecondOtherCurveEndPoint.y);
mOtherPath.lineTo(mNavigationBarWidth, mNavigationBarHeight);
mOtherPath.lineTo(mNavigationBarWidth, 0);
mOtherPath.lineTo(0, 0);
mOtherPath.close();
canvas.drawPath(mOtherPath, mOtherPaint);

结果:

enter image description here

相关问题