实现效果图:
在Android开发中,系统已经帮我们封装好了二阶和三阶的对应实现方法,我们只管调用就行
1.初始化,设置了三个点分别是起始点,控制点和结束点
private void init(Context context) {
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(displayMetrics);
int screenWidth = displayMetrics.widthPixels;
int screenHeight = displayMetrics.heightPixels;
mStartPx = screenWidth / 8;
mStartPy = screenHeight * 3 / 4;
mEndPx = screenWidth * 7 / 8;
mEndPy = screenHeight * 3 / 4;
mControlPx = screenWidth / 2;
mControly = screenHeight / 3;
mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setColor(Color.BLACK);
mPaint.setStrokeWidth(2);
mPaint.setTextSize(30);
mPaint.setStyle(Paint.Style.STROKE);
mTextBond = new RectF();
mPath = new Path();
}
2.先画二条线段起始点到控制点和控制点到结束点的线段
canvas.drawLine(mStartPx, mStartPy, mControlPx, mControly, mPaint);
canvas.drawLine(mControlPx, mControly, mEndPx, mEndPy, mPaint);
3.然后画贝塞尔曲线
mPaint.setStrokeWidth(2);
mPath.moveTo(mStartPx,mStartPy);
mPath.quadTo(mControlPx,mControly,mEndPx,mEndPy);
canvas.drawPath(mPath,mPaint);
完整代码:
@Override
protected void onDraw(Canvas canvas) {
//重置路径
mPath.reset();
//画线段
canvas.drawLine(mStartPx, mStartPy, mControlPx, mControly, mPaint);
canvas.drawLine(mControlPx, mControly, mEndPx, mEndPy, mPaint);
float textWidth = mPaint.measureText("起始点");
//画文字
canvas.drawText("起始点", mStartPx - textWidth / 2, mStartPy + textWidth, mPaint);
canvas.drawText("控制点", mControlPx - textWidth / 2, mControly - textWidth, mPaint);
canvas.drawText("结束点", mEndPx - textWidth / 2, mEndPy + textWidth, mPaint);
//画点
mPaint.setColor(Color.BLUE);
mPaint.setStrokeWidth(20);
canvas.drawPoint(mStartPx,mStartPy,mPaint);
canvas.drawPoint(mControlPx,mControly,mPaint);
canvas.drawPoint(mEndPx,mEndPy,mPaint);
//画贝塞尔曲线
mPaint.setStrokeWidth(2);
mPath.moveTo(mStartPx,mStartPy);
mPath.quadTo(mControlPx,mControly,mEndPx,mEndPy);
canvas.drawPath(mPath,mPaint);
}
4.在onTouchevent中动态改变控制点的位置:
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
mControlPx = (int) event.getX();
mControly = (int) event.getY();
invalidate();
break;
case MotionEvent.ACTION_MOVE:
mControlPx = (int) event.getX();
mControly = (int) event.getY();
invalidate();
break;
}
return true;
}
波浪View的实现,原理就是利用动画逐步移动path
public class WaveView extends View {
private Paint mPaint;
private Path mPath;
private int mScreenWidth;
private int mScreenHeight;
private int offset;
public WaveView(Context context) {
this(context, null);
}
public WaveView(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
init(context);
}
private void init(Context context) {
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics displayMetrics = new DisplayMetrics();
manager.getDefaultDisplay().getMetrics(displayMetrics);
mScreenWidth = displayMetrics.widthPixels;
mScreenHeight = displayMetrics.heightPixels;
mPaint = new Paint();
mPaint.setStyle(Paint.Style.FILL);
mPaint.setAntiAlias(true);
mPaint.setColor(Color.CYAN);
mPaint.setStrokeWidth(4);
mPath = new Path();
doanim();
}
private void doanim() {
ValueAnimator va = ValueAnimator.ofInt(0, mScreenWidth);
va.setRepeatCount(ValueAnimator.INFINITE);
va.setDuration(1000);
va.setInterpolator(new LinearInterpolator());
va.start();
va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
int value = (int) animation.getAnimatedValue();
offset = value;
invalidate();
}
});
}
@Override
protected void onDraw(Canvas canvas) {
mPath.reset();
mPath.moveTo(-mScreenWidth + offset, mScreenHeight / 2);
mPath.quadTo(-mScreenWidth * 3 / 4 + offset, mScreenHeight / 2 - 100, -mScreenWidth / 2 + offset, mScreenHeight / 2);
mPath.quadTo(-mScreenWidth / 4 + offset, mScreenHeight / 2 + 100, offset, mScreenHeight / 2);
mPath.quadTo(mScreenWidth / 4 + offset, mScreenHeight / 2 - 100, mScreenWidth / 2 + offset, mScreenHeight / 2);
mPath.quadTo(mScreenWidth * 3 / 4 + offset, mScreenHeight / 2 + 100,mScreenWidth + offset, mScreenHeight / 2);
mPath.lineTo(mScreenWidth, mScreenHeight);
mPath.lineTo(0, mScreenHeight);
canvas.drawPath(mPath, mPaint);
}
}