/////////继承SurfaceView 的类
public class PaintView extends SurfaceView implements Runnable,SurfaceHolder.Callback {
private float mX;
private float mY;
private Paint mPaint = null;
private Path mPath = null;
// 线程结束标志位
boolean mLoop = true;
SurfaceHolder mSurfaceHolder = null;
Canvas mCanvas; public PaintView(Context context, AttributeSet arr) {
super(context , arr); mSurfaceHolder = this.getHolder();//获取holder
mSurfaceHolder.addCallback(this);
mSurfaceHolder.setFormat(PixelFormat.OPAQUE);//不透明
//mSurfaceHolder.setFormat(PixelFormat.RGB_565);
//mSurfaceHolder.setFormat(PixelFormat.RGBA_8888);
this.setFocusable(true);
// setZOrderOnTop(true);//放到最顶层
mPaint = new Paint();
mPath = new Path();
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeWidth(5);
mPaint.setColor(mPaintColor);
mPaint.setStrokeCap(Paint.Cap.ROUND); //圆头
mPaint.setDither(true);//消除拉动,使画面圓滑
mPaint.setStrokeJoin(Paint.Join.ROUND); //结合方式,平滑
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub } @Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
new Thread(this).start();//启动线程
} @Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
mLoop = false; //结束线程 } @Override
public void run() {
while (mLoop==true) {
Draw();
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
} // 画图
private void Draw() {
try{
mCanvas = mSurfaceHolder.lockCanvas(); mCanvas.drawPath(mPath, mPaint); //// }catch (Exception e){
}finally {
if (mCanvas !=null) {
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
}
} @Override
public boolean onTouchEvent(MotionEvent event)
{
switch (event.getAction())
{
case MotionEvent.ACTION_DOWN:
touchDown(event);
break;
case MotionEvent.ACTION_MOVE:
touchMove(event);
}
//更新绘制
invalidate();
return true;
} //手指点下屏幕时调用
private void touchDown(MotionEvent event)
{
//隐藏之前的绘制
// mPath.reset(); //
float x = event.getX();
float y = event.getY(); mX = x;
mY = y;
//mPath绘制的绘制起点
mPath.moveTo(x, y);
} //手指在屏幕上滑动时调用
private void touchMove(MotionEvent event)
{
final float x = event.getX();
final float y = event.getY(); final float previousX = mX;
final float previousY = mY; final float dx = Math.abs(x - previousX);
final float dy = Math.abs(y - previousY); //两点之间的距离大于等于3时,生成贝塞尔绘制曲线
if (dx >= 3 || dy >= 3)
{
//设置贝塞尔曲线的操作点为起点和终点的一半
float cX = (x + previousX) / 2;
float cY = (y + previousY) / 2; //二次贝塞尔,实现平滑曲线;previousX, previousY为操作点,cX, cY为终点
mPath.quadTo(previousX, previousY, cX, cY); //第二次运行时,第一次结束调用的坐标值将作为第二次调用的初始坐标值
mX = x;
mY = y;
}
}
////橡皮擦
private void setEraser(){
mPaint = new Paint();
mPath = new Path();
mPaint.setAntiAlias(true);
mPaint.setStyle(Style.STROKE);
mPaint.setStrokeWidth(50);
// mPaint.setColor(mPaintColor);
mPaint.setStrokeCap(Paint.Cap.ROUND); //圆头
mPaint.setDither(true);//消除拉动,使画面圓滑
mPaint.setStrokeJoin(Paint.Join.ROUND); //结合方式,平滑
mPaint.setAlpha(0); ////
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
}
}
////////在Activity中显示以上视图
setContentView(new PaintView(this));

在SurfaceView中自由书写和擦除的更多相关文章

  1. 「ReStory」在 Markdown 中自由书写 React 组件 (Beta)

    介绍 先睹为快 我们在开发一个小小的 React 组件库,但是我们遇到了一个大难题,那就是为我们的组件库书写一个合理的文档. 作为组件文档,我们非常希望我们的组件用例代码能够展现出来,是的我们在书写文 ...

  2. Android 动态背景的实现以及SurfaceView中添加EditText控件

    首先还是一贯作风,我们先看案例: \ 静态图看不出来效果,如果用过此软件(扎客)的同学们都知道,她的背景会动.怎么样,是不是觉得很时尚,起码比静态的要好(个人观点).其实实现起来并不复杂,这个如果让做 ...

  3. 深入Animation,在SurfaceView中照样使用Android—Tween Animation!

    第一类:Frame By Frame 帧动画( 不推荐游戏开发中使用)             所谓帧动画,就是顺序播放事先做好的图像,类似于放电影:             分析: 此种方式类似我之 ...

  4. Oracl中sql书写技巧

    1.写脚本(1)为什么不直接设置回滚点?因为服务器上数据库是很多人使用的,所以除了自己操作外,有很多人操作.如果设置回滚点时,回滚后,很多人操作都消失了,因此savepoint不可以.但是可以自己书写 ...

  5. Win32下 Qt与Lua交互使用(四):在Lua脚本中自由执行Qt类中的函数

    话接上篇.通过前几篇博客,我们实现在Lua脚本中执行Qt类中函数的方法,以及在Lua脚本中连接Qt对象的信号与槽. 但是,我们也能发现,如果希望在Lua脚本中执行Qt类的函数,就必须绑定一个真正实现功 ...

  6. MVC5 Razor视图中不规范书写导致的编译问题

    今天碰到一个非常让人难以理解的问题,如图所示,但是我在代码中并没有找到缺失"}"的地方: 根据源文件提示有去 AppData\Local\Temp\Temporary ASP.NE ...

  7. 虚拟现实中自由步行(free-space walking)

    之前我们讲到了虚拟现实中漫游方式的分类.虚拟现实中的漫游(travel/navigate)方式,即是应用提供给用户的,在虚拟环境中移动的方式.虚拟现实的漫游方式中,有一种被称为“完全动作线索”1,即用 ...

  8. android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测

    目录: 1,过程感慨: 2,运行环境: 3,准备工作: 4,编译 .so 5,遇到的关键问题及其解决方法 6,实现效果截图. (原创:转载声明出处:http://www.cnblogs.com/lin ...

  9. android SurfaceView中播放视频 按视频的原始比例播放

    OnPreparedListener mediaPlayerOnPreparedListener = new OnPreparedListener() { @Override public void ...

随机推荐

  1. 初识google多语言通信框架gRPC系列(一)概述

    gRPC概述 3/26/2016 9:16:08 AM 目录 一.概述 二.编译gRPC 三.C#中使用gRPC 四.C++中使用gRPC 一直在寻找多平台多语言的通信框架,微软的WCF框架很强大和灵 ...

  2. EXCEL随机密码生成函数

    =CHAR(INT(RAND()*+))&INT(RAND()*+)&CHAR(INT(RAND()*+))&INT(RAND()*+)&CHAR(INT(RAND() ...

  3. 【转】QT样式表 (QStyleSheet)

    作者:刘旭晖 Raymond 转载请注明出处Email:colorant@163.comBLOG:http://blog.csdn.net/colorant/ 除了子类化Style类,使用QT样式表( ...

  4. 自己写的sql排序

    create function dbo.Fn_Sort (  @str varchar(1024) ) returns nvarchar(100) as begin declare @tb table ...

  5. HDU 4313 Matrix

    水题:在一个双连通的树上有一些点很有破坏性,我们要把这些带破环性的点隔开,就是破坏一些边使这些点之间不连通,破坏一条边需要一点时间,问最少需要多少时间(同一时间只能破坏一个地方,且忽略位置转移的时间) ...

  6. LA3026 - Period(KMP)

    For each prefix of a given string S with N characters (each character has an ASCII code between 97 a ...

  7. Hosting WCF Service

    之前在博客几个实例DemoWCF服务寄宿到控制到应用程序中,这篇来总结一下,经常使用的几种宿主的方式. 1.Self-Hosting 一个WCF服务可以寄宿在控制台应用程序或者WinForms app ...

  8. Android - 和其他APP交互 - 获得activity的返回值

    启用另一个activity不一定是单向的.也可以启用另一个activity并且获得返回值.要获得返回值的话,调用startActivityForResult()(而不是startActivity()) ...

  9. 条形码/二维码之开源利器ZXing图文介绍(转)

    继前面介绍的一个日本开源软件(该软件只能实现QRCode)原文: Java实现二维码QRCode的编码和解码(http://sjsky.iteye.com/blog/1136934 ),今发现又一优秀 ...

  10. [原创].NET 分布式架构开发实战之二 草稿设计

    原文:[原创].NET 分布式架构开发实战之二 草稿设计 .NET 分布式架构开发实战之二 草稿设计 前言:本篇之所以称为草稿设计,是因为设计的都是在纸上完成的.反映了一个思考的过程. 本篇的议题如下 ...