Android 涂鸦最佳实践

泡在网上的日子 / 文 发表于2014-09-09 09:04 次阅读 涂鸦,SurfaceView

Android中实现手势绘图一般都两种方式,一是直接在View上绘制,而是使用SurfaceView。两者还是有一些区别的,简单介绍下。View:显示视图,内置画布,提供图形绘制函数、触屏事件、按键事件函数等;必须在UI主线程内更新画面,速度较慢。 SurfaceView:基于view视图进行拓展的视图类,更适合2D游戏的开发;是view的子类,使用双缓机制,在新的线程中更新画面所以刷新界面速度比view快。所以呢,要实现涂鸦的功能优先选择后者。

在开始码代码之前,先简单理下要实现的功能。

1、可以自定义画笔的颜色

2、可以自定义画笔的粗细

3、可以实现各种常见形状的绘制

4、允许画布的回退,就是回到上一步

5、要支持橡皮擦功能

6、已作完的画,要支持保存

下面我们就逐步去实现这五个功能点。

一、关于自定义画笔的颜色和粗细,这个最简单,只须调用Paint的setColor(int color)和setStrokeWidth(float width)这两个方法即可。需要主要的是,使用SurfaceView绘图需要注意是通过SurfaceHolder获得Canvas实例,这时可以通过Canvas实例去绘图,绘制结束调用unlockCanvasAndPost(canvas)去提交改变。

    @Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = mSurfaceHolder.lockCanvas();
canvas.drawColor(Color.WHITE);
mSurfaceHolder.unlockCanvasAndPost(canvas);
mActions = new ArrayList<Action>();
}

二、支持自由曲线、直线、矩形、圆形、实心矩形、实心圆形,很方便的进行扩展。这里先抽象出一个基类Action,每一次的绘制都是一个action实例,我们的画板就是一个action的列表,这样就能很好的支持回退功能。

public abstract class Action {
public int color;
Action() {
color = Color.BLACK;
}
Action(int color) {
this.color = color;
}
public abstract void draw(Canvas canvas);
public abstract void move(float mx, float my);
}

三、画布的回退。如果画布上的action列表大小不为0,表示画布目前是支持回退的,只须把列表中最后一个action给remove掉,重新绘制就OK了

    public boolean back() {
if (mActions != null && mActions.size() > 0) {
mActions.remove(mActions.size() - 1);
Canvas canvas = mSurfaceHolder.lockCanvas();
canvas.drawColor(Color.WHITE);
for (Action a : mActions) {
a.draw(canvas);
}
mSurfaceHolder.unlockCanvasAndPost(canvas);
return true;
}
return false;
}

四、橡皮擦。这里我取了个巧,画布的背景是白色的,所以橡皮擦的实现也是一个action,形状为自由曲线,颜色也为白色,这样就营造了一种被擦除的效果,其实只是被白色的曲线给遮盖住了。按照第三点的实现,橡皮擦也支持回退。

case R.id.eraser_picker:
mDoodle.setSize(10);
mDoodle.setColor("#ffffff");
break;

五、保存画板。画布上画满了你的各种图形,最后一步就是保存了,但是View和SurfaceView的截取是不同的,View是静态的被动的,SurfaceView是主动的动态的,如果使用View的截图方法只能得到一个黑屏。这时好办法就是把咱们保存的action列表重新绘制出来。代码如下

    /**
* 获取画布的截图
* @return
*/
public Bitmap getBitmap() {
bmp = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
doDraw(canvas);
return bmp;
}

代码地址:https://github.com/JackCho/AndroidDoodle

收藏 赞 (2) 踩 (0)
上一篇:ActionSheetForAndroid安卓版本的ActionSheet
模仿IOS里面的UIActionSheet控件,有IOS6和IOS7两种风格,可以自定义风格,背景图片、按钮图片、文字颜色、间距等。 项目地址: https://github.com/baoyongzhang/ActionSheetForAndroid 使用方法 创建一个ActionSheet并显示 ActionSheet.createBuilder(this
下一篇:android Calendar4.0源码分析之Dayview
事件Event的绘制在drawEvents中完成的。在drawEvents中,绘制event之前会先通过geometry.computeEventRect(date, left, top, cellWidth, event)测量每个event在视图中所占据的矩形区域。然后调用drawEventRect绘制一个矩形,再调用drawEventText绘制文字。测