Android 如何反转曲线底部导航?

Android 如何反转曲线底部导航?,android,canvas,path,Android,Canvas,Path,我发现了一个用画布绘制曲线的库。 我想反转曲线,这样曲线就不会从顶部开始。 曲线应该从底部到顶部。但我现在真的不知道该如何扭转这种局面。我试了两个小时,我不知道怎么画立方体 看起来是这样的: 但我希望它看起来像这样, 它应该只改变曲线,如图所示。 而不是像我为让你明白而做的那样旋转整件事。 只有曲线应该像此屏幕截图中那样绘制: 这是密码 import android.content.Context; import android.graphics.Canvas; import android

我发现了一个用画布绘制曲线的库。 我想反转曲线,这样曲线就不会从顶部开始。 曲线应该从底部到顶部。但我现在真的不知道该如何扭转这种局面。我试了两个小时,我不知道怎么画立方体

看起来是这样的:

但我希望它看起来像这样, 它应该只改变曲线,如图所示。 而不是像我为让你明白而做的那样旋转整件事。 只有曲线应该像此屏幕截图中那样绘制:

这是密码

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

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

  • 0成为navigationbarHeight
  • 导航栏高度变为0
  • 半径变为导航栏高度-半径
我引入了其他变量,以便能够在相同的
视图中绘制两条曲线:

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();
init()中初始化
路径
绘制

onSizeChanged()中设置新变量的值

最后,在
onDraw()中将所有内容拼接在一起

结果:


谢谢,节省了我很多时间。我试图将0更改为navigationbarHeight等,但我不知道为什么它不起作用。我会明白的!
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);
}
// ... 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);
// ... 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);