有人说SurfaceView是View的孪生兄弟,其实SurfaceView也是继承自View的,不过View的绘制只能在主线程,而SurfaceView却可以在子线程中进行绘制。本文我们不介绍SurfaceView的基础用法,只介绍如何使用SurfaceView来制作一个简易写字板。

PreView(gif加载较慢,请耐心等待)

思路

  • 创建一个类继承我们的SurfaceView
  • 通过onTouchEvent来记录手指的滑动轨迹
  • 开启一个子线程来绘制我们手指轨迹

扩展

  • 可以改变画笔的颜色
  • 改变颜色之后之前绘制的图像颜色不变
  • 增加擦除功能

创建PaintSurfaceView


public class PaintSurfaceView extends SurfaceView implements SurfaceHolder.Callback {public static final String TAG = PaintSurfaceView.class.getSimpleName();private SurfaceHolder mHolder;private Paint mPaint;// 是否绘制private boolean isDrawing;private Canvas mCanvas;private Path mPath;public PaintSurfaceView(Context context) {this(context, null);}public PaintSurfaceView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public PaintSurfaceView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);mHolder = getHolder();mHolder.addCallback(this);mPaint = new Paint();//设置抗锯齿mPaint.setAntiAlias(true);//设置画笔的风格mPaint.setStyle(Paint.Style.STROKE);//设置边线的宽度mPaint.setStrokeWidth(10);//设置画笔的颜色mPaint.setColor(Color.BLACK);mPath = new Path();}@Overridepublic void surfaceCreated(SurfaceHolder holder) {isDrawing = true;}@Overridepublic void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {Log.d(TAG, "surfaceChanged: ");}@Overridepublic void surfaceDestroyed(SurfaceHolder holder) {isDrawing = false;Log.d(TAG, "surfaceDestroyed: ");}
}
可以看到这里我们只是做了简单的初始化工作。

通过onTouchEvent记录手指滑动轨迹

@Overridepublic boolean onTouchEvent(MotionEvent event) {int x = (int) event.getX();int y = (int) event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:mPath.moveTo(x, y);return true;case MotionEvent.ACTION_MOVE://记录所有划过的点mPath.lineTo(x, y);return true;}invalidate();return super.onTouchEvent(event);}

在手指落下时,记录手指滑动的起点,move的时候记录滑动路劲。所以这里我们只需要处理ACTION_DOWN和ACTION_MOVE事件即可。

实现Runable接口

  @Overridepublic void run() {while (isDrawing) {try {// 锁定画布mCanvas = mHolder.lockCanvas();myDraw();} catch (Exception e) {Log.d(TAG, "run: " + e.getMessage());} finally {if (mCanvas != null) {// 释放画布mHolder.unlockCanvasAndPost(mCanvas);}}}}public void myDraw() {mCanvas.drawColor(Color.WHITE);mCanvas.drawPath(mPath, mPaint);}

开启绘制线程

 @Overridepublic void surfaceCreated(SurfaceHolder holder) {isDrawing = true;new Thread(this).start();}

在surface创建的时候我们开始绘制,熟悉Java线程的朋友应该知道创建新线程的时候构造需要传一个Runnable对象,所以我们传this即可。

这时候在xml文件引用我们的PaintSurfaceView,运行就可以开始写字了。这时要改变颜色和擦除路径只需要调用mPaint.setColormPath.reset()即可。

但是,问题来了。这种情况下突然改变颜色值,之前绘制的路径颜色也会发生改变,那么我们如何才能不改变之前的颜色呢?答案是我们可以将要绘制的path和color放在一个模型类里面(MVC的思想有木有。。。),然后定义一个集合来管理所有绘制的路径。

定义模型类

/*** 我们需要用到的是Path和color值*/
public class DrawPath {private Path mPath;private int mColor;public DrawPath() {}public DrawPath(Path path, int color) {mPath = path;mColor = color;}public Path getPath() {return mPath;}public void setPath(Path path) {mPath = path;}public int getColor() {return mColor;}public void setColor(int color) {mColor = color;}
}
    此时在PaintSurfaceView中初始化一个List<DrawPath>集合,通过它来管理我们的绘制路径

创建一个改变颜色的方法

 /*** 改变颜色** @param color*/public void changeColor(int color) {mPaint.setColor(color);mPath = new Path();DrawPath path = new DrawPath(mPath, color);mPathList.add(path);}/*** 清除所有*/public void clear() {int size = mPathList.size();DrawPath drawPath = mPathList.get(size - 1);mPathList.clear();mPath = drawPath.getPath();mPath.reset();mPathList.add(drawPath);}

每次改变颜色时,我们创建一个新的DrawPath对象来保存之前的绘制路劲和颜色,并将其放入list集合。再创建了一个擦除方法,用于擦除所有绘制的路径,并保留擦除之前最后选中的颜色。

开始绘制

 public void myDraw() {mCanvas.drawColor(Color.WHITE);for (DrawPath drawPath : mPathList) {mPaint.setColor(drawPath.getColor());mCanvas.drawPath(drawPath.getPath(), mPaint);}}
因为所有的路径信息都保存在mPathList种,所以只需要迭代mPathList,即可实现我们想要的效果。

源码下载

Android之使用SurfaceView制作简易写字板相关推荐

  1. canvas制作简易写字板

    实现思路:鼠标按下,鼠标移动,鼠标松开时所经过的地方进行连接. 实现代码: <canvas id="mycanvas" width="500" heigh ...

  2. js+css+html制作简易留言板

    js+css+html制作简易留言板 1 案例说明 2 编写HTML代码 3 编写css代码 4 编写JavaScript代码 5 全部代码 1 案例说明 利用JavaScript.css以及html ...

  3. Android View与SurfaceView的手绘板制作

    最近学习了如何使用View与SurfaceView制作简单的手绘板,在此做个小结. 自定义VIew实现手绘板: 首先是使用View来实现手绘板: package com.app.superxlcr.m ...

  4. Canvas制作简易涂鸦板

    使用canvas可以做到许多意想不到的功能,尤其动画方面,这次在vue项目中使用canvas制作一个简易涂鸦板 1. html部分代码 <template><div id=" ...

  5. 写字板能制作html,写字板的制作方法

    写字板的制作方法 [专利摘要]一种写字板,包括板体.磁性笔,其特征在于:所述板体的正面上等距间隔地分布有顶部直径小底部直径大的圆锥形的凹孔,所述板体正面上凹孔的俯视投影呈网格状,在每个凹孔内设置有能上 ...

  6. android热成像模块,Arduino制作简易热成像装置

    [项目源起] 学校化学老师要参加省优质课比赛,其中设计了一个化学实验演示环节,其目的是让学生感受到化学反应中能量的变化和分布情况.于是他想请我帮忙设计一个热成像装置,能够以图形化的方式展示化学反应中能 ...

  7. java 语言 写字板_一个简单的java语言写字板.docx

    一个简单的java语言写字板.docx 一个简单的JAVA语言写字板一.需求分析1.需求分析:现在网络上各种文档编辑器数不胜数.功能也是应有尽有,有能改变字体的,有可以改变字体颜色的,但是,这些软件有 ...

  8. 【java毕业设计】基于java+swing的模拟写字板设计与实现(毕业论文+程序源码)——模拟写字板

    基于java+swing的模拟写字板设计与实现(毕业论文+程序源码) 大家好,今天给大家介绍基于java+swing的模拟写字板设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦.需要下载开题报 ...

  9. 【项目精选】基于Java的模拟写字板的设计与实现(视频+论文+源码)

    点击下载源码 此系统是使用Java语言实现简易写字板程序,能够进行输入文字操作,并具有新建文件,打开文件,保存文件,退出,复制,粘贴,剪切,全选,撤销等多种基本功能.本系统结构如下: (1)菜单栏: ...

最新文章

  1. pandas中的reset_index()
  2. 移动手机平台的HTML5前端优化指南
  3. 帝国cms 多个php,帝国cms多值字段数据显示方法
  4. 错误:android.util.SuperNotCalledException
  5. Python中异常处理的用法
  6. 全球19家值得关注的物联网安全初创企业
  7. mysql从表截取信息_mysql中循环截取用户信息并插入到目标表对应的字段中
  8. 调试代码和解决问题的总体思路和 技术路线应该持有的心态
  9. 数值分析(6)-函数逼近的基本概念
  10. feedback vertex set problem (FVS) 反馈顶点集问题 是什么
  11. 用代码生成PDF文档的方法
  12. linux 鼠标残影,Win10系统拖动鼠标有残影怎么办
  13. 华为手机解锁码计算工具_华为最新解bl解锁码计算工具 V2.0.2 免费版
  14. android手机向电脑传输文件,手机怎么用数据线连接电脑传输文件
  15. C#、Asp.net byte转换为GB/MB/KB 方法
  16. 地震数据剖面图-matlab
  17. php获取百度搜索的关键词,【2020年】百度搜索词获取,获取百度搜索的关键词【真实有效】...
  18. centos linux系统后门程序
  19. 强连通分量(Tarjan算法)和缩点
  20. 没有鼠标就无法对计算机进行操作,电脑鼠标不灵敏是什么原因?怎么解决?

热门文章

  1. 不会 ps 没关系,在线一键抠图
  2. 拒绝成为比尔·盖茨的“万维网之父”,又要干大事!
  3. 做UG模具设计师需会哪些技能?
  4. 《移动安全》(8)为挂钩而战-Xposed模块编写
  5. Linux下清除系统日志方法
  6. 数据仓库建设-业务数据调研
  7. ubuntu术后那些事儿
  8. 米酷CMS影视 6.26 源码+解析接口+安装步骤
  9. 安卓逆向——某宝APP抓包之环境对比 (一)
  10. js实现简单聊天页面,图片随机名字随机