本示例要实现一个画图板,当用户在触摸屏上移动时,即可在屏幕上绘制任意的图形。实现手绘功能其实是一种假象:表面上看起来可以随用户在触摸屏上自由地画曲线,实际上依然利用的是 Canvas的 drawline方法画直线,每条直线都是从上一次拖动事件发生点画到本次拖动事件发生点。当用户在触摸屏上移动时,两次拖动事件发生点的距离很小,多条极短的直线连接起来,肉眼看起来就是直线了。借助于 Android提供的Path类,可以非常方便地实现这种效果。
需要指出的是,如果程序每次都只是从上次拖动事件的发生点绘一条直线到本次拖动事件的发生点,那么用户前面绘制的就会丢失。为了保留用户之前绘制的内容,程序要借助于“双缓冲”技术。
所谓双缓冲技术其实很简单:当程序需要在指定Vew上进行绘制时,程序并不直接绘制到该View组件上,而是先绘制到一个内存中的 Bitmap图片(这就是缓冲)上,等到内存中的 Bitmap绘制好之后,再一次性地将 Bitmap绘制到View组件上。
float preX;
float preY;
private Path path;
public Paint paint = null;
public int VIEW_WIDTH = 320;
public int VIEW_HEIGHT = 480;
//定义一个Bitmap,该图片将作为缓冲区
Bitmap cacheBitmap = null;
//定义cacheBitmap上的Canvas对象
Canvas cacheCanvas = null;
public DrawView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
init();
}
private void init() {
cacheBitmap = Bitmap.createBitmap(VIEW_WIDTH,
VIEW_HEIGHT, Bitmap.Config.ARGB_8888);
cacheCanvas = new Canvas();
path = new Path();
//设置cacheCanvas将绘制到内存中的cacheBitmap上
cacheCanvas.setBitmap(cacheBitmap);
paint = new Paint(Paint.DITHER_FLAG);
paint.setColor(Color.RED);
//设置画笔风格
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(5);
//反锯齿
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();
//返回true,表明处理过该事件
return true;
}
@Override
protected void onDraw(Canvas canvas) {
Paint bmpPaint = new Paint();
canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint);//画缓冲图片
canvas.drawPath(path, paint);//画当前轨迹
}
上面是画板简单实现,我们还可以添加另外的功能:改变画笔颜色、画笔宽度、清屏。。。这里就不在多写了。
网友评论