android-API之FingerPaint手指绘图详解

主Activity类DemoViewPath.java

  1. packagecom.geolo.android.demoViewPath;
  2. importandroid.app.Activity;
  3. importandroid.os.Bundle;
  4. publicclassDemoViewPathextendsActivity{
  5. @Override
  6. protectedvoidonCreate(BundlesavedInstanceState){
  7. DemoPathdp=newDemoPath(this);
  8. setContentView(dp);
  9. super.onCreate(savedInstanceState);
  10. }
  11. }
package com.geolo.android.demoViewPath; import android.app.Activity; import android.os.Bundle; public class DemoViewPath extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { DemoPath dp = new DemoPath(this); setContentView(dp); super.onCreate(savedInstanceState); } }

绘图类:DemoPath.java

  1. packagecom.geolo.android.demoViewPath;
  2. importandroid.content.Context;
  3. importandroid.graphics.Bitmap;
  4. importandroid.graphics.Canvas;
  5. importandroid.graphics.Paint;
  6. importandroid.graphics.Path;
  7. importandroid.view.MotionEvent;
  8. importandroid.view.View;
  9. publicclassDemoPathextendsView{
  10. privatefloatmX,mY;
  11. privatePathmPath;
  12. privatePaintmPaint;
  13. privatestaticfinalfloatTOUCH_TOLERANCE=4;
  14. privateBitmapmBitmap;
  15. privateCanvasmCanvas;
  16. privatePaintmBitmapPaint;
  17. publicDemoPath(Contextc){
  18. super(c);
  19. mPaint=newPaint();//创建画笔渲染对象
  20. mPaint.setAntiAlias(true);//设置抗锯齿,让绘画比较平滑
  21. mPaint.setDither(true);//设置递色
  22. mPaint.setColor(0xFFFF0000);//设置画笔的颜色
  23. mPaint.setStyle(Paint.Style.STROKE);//画笔的类型有三种(1.FILL2.FILL_AND_STROKE3.STROKE)
  24. mPaint.setStrokeJoin(Paint.Join.ROUND);//默认类型是MITER(1.BEVEL2.MITER3.ROUND)
  25. mPaint.setStrokeCap(Paint.Cap.ROUND);//默认类型是BUTT(1.BUTT2.ROUND3.SQUARE)
  26. mPaint.setStrokeWidth(12);//设置描边的宽度,如果设置的值为0那么边是一条极细的线
  27. mBitmap=Bitmap.createBitmap(320,480,Bitmap.Config.ARGB_8888);//绘制固定大小的bitmap对象
  28. mCanvas=newCanvas(mBitmap);//将固定的bitmap对象嵌入到canvas对象中
  29. mPath=newPath();//创建画笔路径
  30. mBitmapPaint=newPaint(Paint.DITHER_FLAG);
  31. }
  32. @Override
  33. protectedvoidonDraw(Canvascanvas){
  34. canvas.drawColor(0xFFAAAAAA);
  35. canvas.drawBitmap(mBitmap,0,0,mBitmapPaint);
  36. canvas.drawPath(mPath,mPaint);
  37. super.onDraw(canvas);
  38. }
  39. privatevoidonTouchDown(floatx,floaty){
  40. mPath.reset();//将上次的路径保存起来,并重置新的路径。
  41. mPath.moveTo(x,y);//设置新的路径“轮廓”的开始
  42. mX=x;
  43. mY=y;
  44. }
  45. privatevoidonTouchMove(floatx,floaty){
  46. floatdx=Math.abs(x-mX);
  47. floatdy=Math.abs(y-mY);
  48. if(dx>=TOUCH_TOLERANCE||dy>=TOUCH_TOLERANCE){
  49. mPath.quadTo(mX,mY,(x+mX)/2,(y+mY)/2);
  50. mX=x;
  51. mY=y;
  52. }
  53. }
  54. privatevoidonTouchUp(floatx,floaty){
  55. mPath.lineTo(mX,mY);//从最后一个指定的xy点绘制一条线,如果没有用moveTo方法,那么起始点表示(0,0)点。
  56. //committhepathtoouroffscreen
  57. mCanvas.drawPath(mPath,mPaint);//手指离开屏幕后,绘制创建的“所有”路径。
  58. //killthissowedon'tdoubledraw
  59. mPath.reset();
  60. }
  61. @Override
  62. publicbooleanonTouchEvent(MotionEventevent){
  63. floatx=event.getX();
  64. floaty=event.getY();
  65. switch(event.getAction()){
  66. caseMotionEvent.ACTION_DOWN://手指开始按压屏幕,这个动作包含了初始化位置
  67. onTouchDown(x,y);
  68. invalidate();//刷新画布,重新运行onDraw()方法
  69. break;
  70. caseMotionEvent.ACTION_MOVE://手指按压屏幕时,位置的改变触发,这个方法在ACTION_DOWN和ACTION_UP之间。
  71. onTouchMove(x,y);
  72. invalidate();
  73. break;
  74. caseMotionEvent.ACTION_UP://手指离开屏幕,不再按压屏幕
  75. onTouchUp(x,y);
  76. invalidate();
  77. break;
  78. default:
  79. break;
  80. }
  81. returntrue;
  82. }
  83. }
package com.geolo.android.demoViewPath; import android.content.Context; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.view.MotionEvent; import android.view.View; public class DemoPath extends View { private float mX , mY; private Path mPath; private Paint mPaint; private static final float TOUCH_TOLERANCE = 4; private Bitmap mBitmap; private Canvas mCanvas; private Paint mBitmapPaint; public DemoPath(Context c) { super(c); mPaint = new Paint();//创建画笔渲染对象 mPaint.setAntiAlias(true);//设置抗锯齿,让绘画比较平滑 mPaint.setDither(true);//设置递色 mPaint.setColor(0xFFFF0000);//设置画笔的颜色 mPaint.setStyle(Paint.Style.STROKE);//画笔的类型有三种(1.FILL 2.FILL_AND_STROKE 3.STROKE ) mPaint.setStrokeJoin(Paint.Join.ROUND);//默认类型是MITER(1.BEVEL 2.MITER 3.ROUND ) mPaint.setStrokeCap(Paint.Cap.ROUND);//默认类型是BUTT(1.BUTT 2.ROUND 3.SQUARE ) mPaint.setStrokeWidth(12);//设置描边的宽度,如果设置的值为0那么边是一条极细的线 mBitmap = Bitmap.createBitmap(320, 480, Bitmap.Config.ARGB_8888);//绘制固定大小的bitmap对象 mCanvas = new Canvas(mBitmap);//将固定的bitmap对象嵌入到canvas对象中 mPath = new Path();//创建画笔路径 mBitmapPaint = new Paint(Paint.DITHER_FLAG); } @Override protected void onDraw(Canvas canvas) { canvas.drawColor(0xFFAAAAAA); canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint); canvas.drawPath(mPath, mPaint); super.onDraw(canvas); } private void onTouchDown(float x , float y){ mPath.reset();//将上次的路径保存起来,并重置新的路径。 mPath.moveTo(x, y);//设置新的路径“轮廓”的开始 mX = x; mY = y; } private void onTouchMove(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 onTouchUp(float x , float y){ mPath.lineTo(mX, mY);//从最后一个指定的xy点绘制一条线,如果没有用moveTo方法,那么起始点表示(0,0)点。 // commit the path to our offscreen mCanvas.drawPath(mPath, mPaint);//手指离开屏幕后,绘制创建的“所有”路径。 // kill this so we don't double draw mPath.reset(); } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN://手指开始按压屏幕,这个动作包含了初始化位置 onTouchDown(x , y); invalidate();//刷新画布,重新运行onDraw()方法 break; case MotionEvent.ACTION_MOVE://手指按压屏幕时,位置的改变触发,这个方法在ACTION_DOWN和ACTION_UP之间。 onTouchMove(x , y); invalidate(); break; case MotionEvent.ACTION_UP://手指离开屏幕,不再按压屏幕 onTouchUp(x , y); invalidate(); break; default: break; } return true; } }

--------------------------------------------------

(1)在我们的应用中,无论绘制什么图形,我们只用到一个画笔。(如果我们将画笔的颜色设置为蓝色,我们画出的矩形、椭圆都将是蓝色的。)

(2)我们需要对画笔进行设置,然后所绘制的图形随之改变,而我们又不想在图形类的draw方法中“new”。

所以,我们需要应用单例模式,保证在我们的应用中只存在一个唯一的画笔实例。

单例画笔类Brush的源码如下:

  1. packageorg.vhow.paintpad.tools;
  2. importandroid.graphics.Paint;
  3. /**
  4. *UseSingletonmodetocreateBrushclass
  5. */
  6. publicclassBrushextendsPaint
  7. {
  8. /**
  9. *Generatetheinstancewhentheclassisloaded
  10. */
  11. privatestaticBrushbrush=newBrush();
  12. /**
  13. *Maketheconstructorprivate,tostopotherstocreateinstancebythe
  14. *defaultconstructor
  15. */
  16. privateBrush()
  17. {
  18. }
  19. /**
  20. *Provideastaticmethodthatcanbeaccessbyothers.
  21. *
  22. *@returnthesingleinstance
  23. */
  24. publicstaticBrushgetPen()
  25. {
  26. returnbrush;
  27. }
  28. /**
  29. *resetthebrush
  30. */
  31. publicvoidreset()
  32. {
  33. brush.setAntiAlias(true);
  34. brush.setDither(true);
  35. brush.setColor(0xFF000000);
  36. brush.setStyle(Paint.Style.STROKE);
  37. brush.setStrokeJoin(Paint.Join.ROUND);
  38. brush.setStrokeCap(Paint.Cap.ROUND);
  39. brush.setStrokeWidth(2);
  40. }
  41. }



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值