文档章节

双缓冲实现涂鸦view

jacky_123
 jacky_123
发布于 2015/03/03 14:26
字数 434
阅读 10
收藏 1

所谓的双缓冲技术其实很简单,当程序需要在指定的view上进行绘制是,程序并不直接绘制到View组件上,而是先绘制到一个内存中的Bitmap中(这就是缓冲),等到Bitmap绘制好了,再一次性将Bitmap绘制到这个View组件上。

下面,定义了

cacheBitmap:该图片将作为缓冲区

cacheCanvas: 定义cacheBitmap上的Canvas对象

通过cacheCanvas = new Canvas(cacheBitmap)将两者练习到一起。

代码很简单,如下,不解释了

public class DrawView extends View
{
 float preX;
 float preY;
 private Path path;
 public Paint paint = null;
 // 定义一个内存中的图片,该图片将作为缓冲区
 Bitmap cacheBitmap = null;
 // 定义cacheBitmap上的Canvas对象
 Canvas cacheCanvas = null;
 public DrawView(Context context, AttributeSet set)
 {
  super(context, set);
  /**
   * 获取屏幕的宽高
   */
  WindowManager wm = (WindowManager) context
    .getSystemService(Context.WINDOW_SERVICE);
  DisplayMetrics outMetrics = new DisplayMetrics();
  wm.getDefaultDisplay().getMetrics(outMetrics);
  int screenWidth = outMetrics.widthPixels;
  int screenHeight = outMetrics.heightPixels;
  
  // 创建一个与该View相同大小的缓存区
  cacheBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
    Config.ARGB_8888);
  // 设置cacheCanvas将会绘制到内存中的cacheBitmap上
  cacheCanvas = new Canvas(cacheBitmap);
  path = new Path();
  // 设置画笔的颜色
  paint = new Paint(Paint.DITHER_FLAG);
  paint.setColor(Color.RED);
  // 设置画笔风格
  paint.setStyle(Paint.Style.STROKE);
  paint.setStrokeWidth(1);
  // 反锯齿
  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;
  }
  /**
   * 通知view重绘可调用invalidate() UI线程中
   * 或者postInvalidate  非UI线程中
   */
  invalidate();
  // 返回true表明处理方法已经处理该事件
  return true;
 }
 @Override
 public void onDraw(Canvas canvas)
 {
  Paint bmpPaint = new Paint();
  // 将cacheBitmap绘制到该View组件上
  canvas.drawBitmap(cacheBitmap, 0, 0, bmpPaint); // ②
  // 沿着path绘制
  canvas.drawPath(path, paint);
 }
}

 

参考:疯狂android讲义 p355

        例子:HandDraw

© 著作权归作者所有

共有 人打赏支持
jacky_123
粉丝 3
博文 55
码字总数 26297
作品 0
南通
程序员
Android中UI(View)的刷新

看了很多资料,翻啊翻啊,似乎有些了解了。 Android中对View的更新有很多种方式,使用时要区分不同的应用场合。我感觉最要紧的是分清:多线程和双缓冲的使用情况。 现在可以尝试理解下面的模...

DreamWorker
2010/10/30
0
4
Android-SurfaceView与SurfaceHolder对象

1、Android-SurfaceView与SurfaceHolder对象: http://blog.csdn.net/andyhuabing/article/details/7657069 2、Android学习之 VideoView,SurfaceView: http://blog.csdn.net/abidepan/arti......

当空皓月
2014/12/18
0
0
【Android游戏开发十四】深入Animation,在SurfaceView中照样使用Android—Tween Animation!

李华明Himi 原创,转载务必在明显处注明: 转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/android-game/331.html 很多童鞋说我的代码运行后,点击home或者back后会程序异常,...

迷途d书童
2012/03/19
0
0
项目需求讨论:截图—涂鸦—分享

大家好,又到了新的一期项目需求分析。台下的观众举起手,让我看到你们。 同时我已经上传该项目:截屏及仿支付宝涂鸦功能 欢迎各位点个star哦。(⊙o⊙) 开始秋名山飘移之路 这个也是具体项目...

青蛙要fly
2017/04/12
0
0
Android 带你撸一个好玩的 DoodleView(涂鸦)

本篇文章已授权微信公众号 guolin_blog (郭霖)独家发布 前言 最近项目中需要用到涂鸦的功能,在 Github 上搜了一圈也没找到适合的库,索性就自己撸一个出来,正好复习一下自定义 View 的知...

developerHaoz
2017/07/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

centos7安装rsync及两台机器进行文件同步

centos7安装rsync及两台机器进行文件同步 2017年12月21日 11:17:46 码农下的天桥 阅读数:2210 标签: centosrsync同步 更多 个人分类: 后端 所属专栏: 研发模式及运维 版权声明:本文为博...

linjin200
14分钟前
1
0
jpg、jpeg、png... 的区别

jpg、jpeg、png... 的区别 对于做设计这一行的人来说,这几个图片格式是最常用的,也是最常见的,几乎每一天都要与他们打交道。 刚刚入门的新人通常不知道在什么地方如何使用他们或者说如何更...

DemonsI
33分钟前
4
0
白话SpringCloud | 第十章:路由网关(Zuul)进阶:过滤器、异常处理

前言 简单介绍了关于Zuul的一些简单使用以及一些路由规则的简单说明。而对于一个统一网关而言,需要处理各种各类的请求,对不同的url进行拦截,或者对调用服务的异常进行二次处理等等。今天,...

oKong
38分钟前
2
0
Character的static方法

基本类型char的包装类是Character,使用的比较多,大家是比较熟悉的。 我只是觉得里面有很多static方法,平时不怎么用,学习一下怎么实现的,或许日后就用到了。 static int compare(char x,...

woshixin
51分钟前
1
0
正则介绍_sed

10月17日任务 9.4/9.5 sed sed工具 匹配打印 -n 只打印匹配行,不然其他行也会打印出来 p 打印(配合-n使用) [root@centos7 tmp]# sed -n '/root/'p passwd root:x:0:0:root:/root:/bin/ba...

robertt15
51分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部