1.如果直接在自定义view的触摸事件中绘制图像
则每次虽然会执行绘制方法,但是上一次的绘制就没了。
所以每次要绘制之前,在view的触摸事件中先将路径保存绘制到bitmap上(缓冲区),然后在绘制ondraw()中,只需绘制bitmap的内容即可.
2.代码如下:
public class Main3Activity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); LinearLayout layout = new LinearLayout(this); DisplayMetrics displayMetrics = new DisplayMetrics(); getWindowManager().getDefaultDisplay().getRealMetrics(displayMetrics); MyPathView myPathView = new MyPathView(this , displayMetrics.widthPixels , displayMetrics.heightPixels); layout.addView(myPathView); setContentView(layout); } class MyPathView extends View { float prex; float prey; private Path path; public Paint paint = null; Bitmap cachebitmap = null; //定义一个位图缓冲区 Canvas cachecanvas = null; //定义缓冲区上的画布 public MyPathView(Context context, int widthPixels, int heightPixels) { super(context); cachebitmap = Bitmap.createBitmap(widthPixels , heightPixels , Bitmap.Config.ARGB_8888); //ARGB_8888:每个像素存储在4个字节上 cachecanvas = new Canvas(); path = new Path(); //设置画布内容绘制到bitmap上 cachecanvas.setBitmap(cachebitmap); paint = new Paint(Paint.DITHER_FLAG); paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); paint.setAntiAlias(true); //去锯齿 paint.setDither(true); //去抖动 } @Override public boolean onTouchEvent(MotionEvent event) { float x = event.getX(); float y = event.getY(); switch (event.getAction()) { case MotionEvent.ACTION_DOWN: path.moveTo( x , y ); prex = x; //把当前点当作下一次绘制的第一个点 prey = y; break; case MotionEvent.ACTION_MOVE: path.quadTo(prex , prey , x , y); prex = x; prey = y; break; case MotionEvent.ACTION_UP: //一次触摸事件完成后,绘制到缓冲区(所有触摸事件的路径,都绘制保存在里面) cachecanvas.drawPath(path , paint); path.reset(); //路径重置,用于下一次触摸事件的路径的保存 break; } invalidate(); //有更新了,通知重新执行onDraw()方法 return true; } @Override protected void onDraw(Canvas canvas) { Paint bmppaint = new Paint(); //将缓冲区的内容绘制出来,更新 canvas.drawBitmap(cachebitmap , 0 , 0 ,bmppaint); //在每一次的触摸还没结束之前,要把该次的路径绘制出来 canvas.drawPath(path , paint); } } }
3.效果如下:
4.可以设置画笔paint的绘制效果
Paint bmppaint = new Paint(); //将缓冲区的内容绘制出来,更新 canvas.drawBitmap(cachebitmap , 0 , 0 ,bmppaint); //在每一次的触摸还没结束之前,要把该次的路径绘制出来 //paint.setStrokeWidth(10);可以设置画笔宽度 //paint.setMaskFilter(new BlurMaskFilter( 8 , BlurMaskFilter.Blur.NORMAL));//喷涂效果(模糊效果),(半径 ,效果类型) //paint.setMaskFilter(new EmbossMaskFilter(new float[]{1.5f , 1.5f , 1.5f} , 0.6f , 6 , 4.2f));//浮雕效果(第一个参数为光源照射方向的xyz坐标,第二个参数为光源的数量取值0~1,第三个参数为关照的反射系数一般为6 , 第四个参数为光照前喷涂的范围) canvas.drawPath(path , paint);