各位大神,我最近在做一个Android的作品,想要实现在一个画布上面写字。 里面有一个功能:想要根据用户触屏时间,修改笔画粗细。   
我现在已经实现了能够根据触屏时间,修改整个笔画的粗细,但是,我想更进一步,能不能修改用户点击的点附近的笔画粗细。
代码如下(有写注释,如果熟悉的话,应该 很容易看懂):
package com.ink;import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.*;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageView;public class ChirographyView extends ImageView{
private Bitmap mBitmap;//用于保存所画图像的图画
private Canvas mCanvas;//用于保存所画图像的画布
private Path    mPath, rPath;
private Paint mBitmapPaint;// 画布的画笔
private Paint mPaint;// 真实的画笔
private String nameOfPhoto;  //图片名字
private float mX, mY, tx, ty, tX=0, tY=0;
    private static final float TOUCH_TOLERANCE = 4;
private Calendar starttime;        //笔画开始时间
private Calendar endtime;         //笔画结束时间
    
    
// 保存Path路径的集合,用List集合来模拟栈
private static List<DrawPath> savePath;
// 记录Path路径的对象
private DrawPath dp;

private class DrawPath {
public Path path;// 路径
public Paint paint;// 画笔
}

// Matrix 实例
private Matrix matrix = new Matrix();
// 位图宽和高
private int w, h;
// 判断平移
public boolean isTranslate = false;
    
/*******
在XML中使用自定义View必须要使用含AttributeSet变量参数的构造函数
******/
    public ChirographyView(Context context, AttributeSet attrs) {
     super(context, attrs);
    
     mBitmapPaint = new Paint(Paint.DITHER_FLAG);
     mPaint = new Paint();
     /*********设置画笔********/
     mPaint.setColor(Color.WHITE);
     mPaint.setAntiAlias(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);// 设置外边缘
mPaint.setStrokeCap(Paint.Cap.SQUARE);// 形状
mPaint.setStrokeWidth(1);// 画笔宽度
     savePath = new ArrayList<DrawPath>();
     nameOfPhoto = "text";
    }   public void setBitmap(Bitmap b){
   mBitmap=b;
   mCanvas = new Canvas(mBitmap);
   // 获得位图宽
   w = mBitmap.getWidth();
   // 获得位图高
   h = mBitmap.getHeight();
    }    @Override
   protected void onDraw(Canvas canvas) {
       super.onDraw(canvas);    
    
      canvas.drawBitmap(mBitmap, matrix, null);//把之前画出来保存后的图再画出来
        if(!isTranslate){
         if (rPath != null) {
     // 实时的显示
     canvas.drawPath(rPath, mPaint);
     }
        
        }
        
        else{
        matrix.reset();
        matrix.setTranslate(tx+tX, ty+tY);
        // 根据原始位图和Matrix创建新视图
      Bitmap bm = Bitmap.createBitmap(mBitmap, 0, 0, w, h, matrix, true);
      // 绘制新视图
      canvas.drawBitmap(bm, matrix, null);
        }
    }
    
    private void touch_start(float x, float y) {
     starttime = Calendar.getInstance();
     mX = x;
        mY = y;
     if(!isTranslate){
     // 每次down下去重新new一个Path
mPath = new Path();
rPath = new Path();
//每一次记录的路径对象是不一样的
dp = new DrawPath();
dp.path = mPath;

dp.paint = mPaint;
     mPath.moveTo(x-tX, y-tY);
     rPath.moveTo(x, y);
     invalidate();
     }
    }
    private void touch_move(float x, float y) {
     if(!isTranslate){
            float dx = Math.abs(x - mX);
            float dy = Math.abs(y - mY);
            if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
                mPath.quadTo(mX-tX, mY-tY, (x + mX)/2-tX, (y + mY)/2-tY);
                rPath.quadTo(mX, mY, (x + mX)/2, (y + mY)/2);
                mX = x;
                mY = y;
                endtime = Calendar.getInstance();
            
             int second = endtime.get(Calendar.SECOND) - starttime.get(Calendar.SECOND);
             int mimute = endtime.get(Calendar.MINUTE) - starttime.get(Calendar.MINUTE);
             mPaint.setStrokeWidth(5+second);
            }
         }
         else{
         endtime = Calendar.getInstance();
            
             int second = endtime.get(Calendar.SECOND) - starttime.get(Calendar.SECOND);
             int mimute = endtime.get(Calendar.MINUTE) - starttime.get(Calendar.MINUTE);
             mPaint.setStrokeWidth(5+second);
         tx = x-mX;
                ty = y-mY;
         }
         invalidate();
        }
    private void touch_up() {
    
    
     if(!isTranslate){
            mPath.lineTo(mX-tX, mY-tY);
            rPath.lineTo(mX, mY);
     mCanvas.drawPath(mPath, mPaint);
     savePath.add(dp);
     mPath = null;// 重新置空
     rPath = null;
         invalidate();
         }
         else{
         tX+= tx;
         tY+= ty;
         }
        }
    
    /**
 * 撤销的核心思想就是将画布清空,
 * 将保存下来的Path路径最后一个移除掉,
 * 重新将路径画在画布上面。
 */
public void backout(boolean back) {
mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.test1).copy(Bitmap.Config.ARGB_8888, true);
mCanvas.setBitmap(mBitmap);// 重新设置画布,相当于清空画布 
// 清空画布,但是如果图片有背景的话,则使用上面的重新初始化的方法,用该方法会将背景清空掉...
if (savePath != null && savePath.size() > 0 && back == true) {
// 移除最后一个path,相当于出栈操作
savePath.remove(savePath.size() - 1); Iterator<DrawPath> iter = savePath.iterator();
while (iter.hasNext()) {
DrawPath drawPath = iter.next();
mCanvas.drawPath(drawPath.path, drawPath.paint);
}
}
else
savePath.clear();
invalidate();// 刷新
}

    @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);
                break;
            case MotionEvent.ACTION_MOVE:
                touch_move(x, y);
                break;
            case MotionEvent.ACTION_UP:
                touch_up();
                break;
        }
        return true;
}    
    public String getName(){
     return nameOfPhoto;
    }
    
    public void setName(String name){
     nameOfPhoto = name;
    }
  
}