贝塞尔曲线是应用于二维图形应用程序的数学曲线。
曲线的定义有四个点:起始点、终止点(也称锚点)以及两个相互分离的中间点。滑动两个中间点,贝塞尔曲线的形状会发生变化
import android.app.Activity;import android.os.Bundle;import android.content.Context;import android.graphics.*;import android.view.MotionEvent;import android.view.View;public class TouchScreenActivity extends Activity { private Paint mPaint; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new TouchView(this)); mPaint = new Paint(); mPaint.setAntiAlias(true); //设置抗锯齿,让绘画比较平滑 mPaint.setDither(true); //设置递色 mPaint.setColor(0xFF00FF00); mPaint.setStyle(Paint.Style.STROKE); mPaint.setStrokeJoin(Paint.Join.ROUND); mPaint.setStrokeCap(Paint.Cap.ROUND); mPaint.setStrokeWidth(10); } public class TouchView extends View { private Bitmap mBitmap; private Canvas mCanvas; private Path mPath; private Paint mBitmapPaint; public TouchView(Context c) { super(c); /* android.graphics.Bitmap.Config是一个枚举类型,里面定义了位图的四种格式 * ALPHA_8:数字为8,图形参数应该由一个字节来表示,应该是一种8位的位图 ARGB_4444:4+4+4+4=16,图形的参数应该由两个字节来表示,应该是一种16位的位图. ARGB_8888:8+8+8+8=32,图形的参数应该由四个字节来表示,应该是一种32位的位图. RGB_565:5+6+5=16,图形的参数应该由两个字节来表示,应该是一种16位的位图. 网上讲,ALPHA_8,ARGB_4444,ARGB_8888都是透明的位图,也就是所字母A代表透明. ARGB_4444:意味着有四个参数,即A,R,G,B,每一个参数由4bit表示. 同理: ARGB_8888:意味着有四个参数,即A,R,G,B,每一个参数由8bit来表示. 同理: RGB_565:意味着有三个参数,R,G,B,三个参数分别占5bit,6bit,5bit. */ mBitmap = Bitmap.createBitmap(480, 800, Bitmap.Config.RGB_565); mCanvas = new Canvas(mBitmap); mPath = new Path(); mBitmapPaint = new Paint(Paint.DITHER_FLAG); } @Override protected void onDraw(Canvas canvas) { canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); } private float mX, mY; //只有当移动的距离大于4px时,才在屏幕上绘图 private static final float TOUCH_TOLERANCE = 4; private void touch_start(float x, float y) { mPath.reset(); mPath.moveTo(x, y); mX = x; mY = y; } private void touch_move(float x, float y) { float dx = Math.abs(x - mX); float dy = Math.abs(y - mY); if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) { mPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);//二次方贝塞尔曲线 mX = x; mY = y; } } private void touch_up() { mPath.lineTo(mX, mY); mCanvas.drawPath(mPath, mPaint); mPath.reset(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: touch_start(x, y); invalidate(); break; case MotionEvent.ACTION_MOVE: touch_move(x, y); invalidate(); break; case MotionEvent.ACTION_UP: touch_up(); invalidate(); break; } return true; } } }