android-API之FingerPaint手指绘图详解

来源:互联网 发布:unity 象棋源码 编辑:程序博客网 时间:2024/04/29 10:37

主Activity类DemoViewPath.java

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

 

绘图类:DemoPath.java

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

 

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

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

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

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

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

view plainprint?
  1. package org.vhow.paintpad.tools;  
  2.   
  3. import android.graphics.Paint;  
  4.   
  5. /** 
  6.  * Use Singleton mode to create Brush class 
  7.  */  
  8. public class Brush extends Paint  
  9. {  
  10.     /** 
  11.      * Generate the instance when the class is loaded 
  12.      */  
  13.     private static Brush brush = new Brush();  
  14.   
  15.     /** 
  16.      * Make the constructor private, to stop others to create instance by the 
  17.      * default constructor 
  18.      */  
  19.     private Brush()  
  20.     {  
  21.     }  
  22.   
  23.     /** 
  24.      * Provide a static method that can be access by others. 
  25.      *  
  26.      * @return the single instance 
  27.      */  
  28.     public static Brush getPen()  
  29.     {  
  30.         return brush;  
  31.     }  
  32.   
  33.     /** 
  34.      * reset the brush 
  35.      */  
  36.     public void reset()  
  37.     {  
  38.         brush.setAntiAlias(true);  
  39.         brush.setDither(true);  
  40.         brush.setColor(0xFF000000);  
  41.         brush.setStyle(Paint.Style.STROKE);  
  42.         brush.setStrokeJoin(Paint.Join.ROUND);  
  43.         brush.setStrokeCap(Paint.Cap.ROUND);  
  44.         brush.setStrokeWidth(2);  
  45.     }