我找到了一个https://github.com/androidtutorialonline/CurvedBottomNavigationView库,该库用画布绘制了一条曲线。 我想反转曲线,以使曲线不会从顶部开始。 曲线应从底部到顶部。但是我现在真的不知道如何将其反转。我从2个小时开始尝试,我不知道该如何绘制立方体。
它看起来像这样:
但是我希望它看起来像这样, 它只应更改此图中的曲线。 而且不要像我所做的那样旋转整个过程以使您清楚。 只能按照以下屏幕截图所示绘制曲线:
有密码
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);
}
}
答案 0 :(得分:1)
由于要在x轴上镜像给定曲线,因此必须更改所有点的y坐标。例子:
我引入了其他变量,以便能够在同一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
中的Paint
和init()
:
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);
结果: