activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical"> <com.bse.Baisaier android:id="@+id/custom_path" android:layout_weight="1" android:layout_width="match_parent" android:layout_height="match_parent" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btn"/> </LinearLayout>
MainActivity.java
package com.bse; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
Baisaier.java
package com.bse; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.PointF; import android.support.annotation.Nullable; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * Created by lenovo on 2017/11/03. */ public class Baisaier extends View { private Paint mPaint; private int centerX, centerY; private PointF start, end, control1, control2; private boolean mode = true; public Baisaier(Context context) { super(context); } public Baisaier(Context context, @Nullable AttributeSet attrs) { super(context, attrs); mPaint = new Paint(); mPaint.setColor(Color.BLACK); mPaint.setStrokeWidth(8); mPaint.setStyle(Paint.Style.STROKE); mPaint.setTextSize(60); start = new PointF(0, 0); end = new PointF(0, 0); control1 = new PointF(0, 0); control2 = new PointF(0, 0); } public Baisaier(Context context, @Nullable AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } float x ; float y ; @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); centerX = w/2; centerY = h/2; // 初始化数据点和控制点的位置 start.x = centerX-200; start.y = centerY; end.x = centerX + 200; end.y = centerY; control1.x = centerX; control1.y = centerY - 100; control2.x = centerX; control2.y = centerY - 100; } @Override public boolean onTouchEvent(MotionEvent event) { // 根据触摸位置更新控制点,并提示重绘 if (mode) { control1.x = event.getX(); control1.y = event.getY(); } else { control2.x = event.getX(); control2.y = event.getY(); } invalidate(); return true; } public boolean getMode() { return mode; } public void setMode(boolean mode) { this.mode = mode; } @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); // 绘制数据点和控制点 mPaint.setColor(Color.GRAY); mPaint.setStrokeWidth(20); canvas.drawPoint(start.x, start.y, mPaint); canvas.drawPoint(end.x, end.y, mPaint); canvas.drawPoint(control1.x, control1.y, mPaint); canvas.drawPoint(control2.x, control2.y, mPaint); // 绘制辅助线 mPaint.setStrokeWidth(4); canvas.drawLine(start.x, start.y, control1.x, control1.y, mPaint); canvas.drawLine(control1.x, control1.y,control2.x, control2.y, mPaint); canvas.drawLine(control2.x, control2.y,end.x, end.y, mPaint); // 绘制贝塞尔曲线 mPaint.setColor(Color.RED); mPaint.setStrokeWidth(8); Path path = new Path(); path.moveTo(start.x, start.y); path.cubicTo(control1.x, control1.y, control2.x,control2.y, end.x, end.y); canvas.drawPath(path, mPaint); } }