文档章节

双缓冲实现涂鸦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

没有更多内容

加载失败,请刷新页面

加载更多

下一页

人生苦短:Python里的17个“超赞操作

人生苦短,我选Python”。那么,你真的掌握了Python吗? 1. 交换变量 有时候,当我们要交换两个变量的值时,一种常规的方法是创建一个临时变量,然后用它来进行交换。比如: # 输入 a = 5 b ...

糖宝lsh
37分钟前
4
0
咕泡-spring中常用设计模式概述

设计模式就是经验之谈,供后人借鉴,解决一些具有代表性的问题 设计模式来源于生活,反过来帮助我们更好生活 设计模式提升代码的可读性、可扩展性、维护成本、复杂业务问题 千万不要死记硬背...

职业搬砖20年
今天
2
0
day59-20180817-流利阅读笔记-待学习

假·照骗,真·社交焦虑 雪梨 2018-08-17 1.今日导读 发朋友圈之前,不少人为了展现更美好的生活状态会对照片加以“微调”,或是加个滤镜显得逼格更高,或是磨个皮瘦个脸拉个大长腿。现在,国...

aibinxiao
今天
18
0
OSChina 周五乱弹 —— 姑娘在这个节日里表白你接受么?

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @Sharon啊:完全被这个小姐姐圈粉了,学两首她的歌去哈哈 分享王贰浪的单曲《往后余生(翻自 马良)》 《往后余生(翻自 马良)》- 王贰浪 手...

小小编辑
今天
846
16
为什么HashMap要自己实现writeObject和readObject方法?

为什么HashMap要自己实现writeObject和readObject方法? 如果你有仔细阅读过HashMap的源码,那么你一定注意过一个问题:HashMap中有两个私有方法。 private void writeObject(java.io.Objec...

DemonsI
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部