文档章节

双缓冲实现涂鸦view

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

精选30+云产品,助力企业轻松上云!>>>

所谓的双缓冲技术其实很简单,当程序需要在指定的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
南通
程序员
私信 提问
加载中
请先登录后再评论。
涂鸦画笔功能的实现

之前自定义呼吸圈按钮控件的时候使用到了paint的xfermode,这次要实现涂鸦画笔自然也少不了使用它。由此可见在Android绘图中xfermode的重要性。想要了解Xfermode可以看我的文章仿抖音短视频录...

osc_tm2zceka
2018/06/25
2
0
精彩案例

一、图片相关 1、帮美女脱衣服 (removeClothForBeautyGirl) a、利用反射机制得到drawableId drawableId = R.drawable.class.getDeclaredField("pre" + position).getInt(this); b、初始化m......

jacky_123
2015/03/02
22
0
Android应用概述

1、拼图游戏 imooc-拼图小游戏 2、刮刮乐游戏 Android 自定义控件实现刮刮卡效果 真的就只是刮刮卡么 Demoyjf02GuaGuaKa 相关:双缓冲实现涂鸦view 3、SurfaceView打造抽奖转盘 Android Surf...

jacky_123
2015/03/05
29
0
Android中UI(View)的刷新

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

DreamWorker
2010/10/30
1.4W
4
android中invalidate()的自动清屏含义以及屏幕刷新

invalidate()是用来刷新View的,必须是在UI线程中进行工作。比如在修改某个view的显示时,调用invalidate()才能看到重新绘制的界面。invalidate()的调用是把之前的旧的view从主UI线程队列中p...

kaiyuan2014
2014/05/09
47
0

没有更多内容

加载失败,请刷新页面

加载更多

你看起来很好吃

你看起来很好吃 本文分享自微信公众号 - ZackSock(ZackSock)。 如有侵权,请联系 support@oschina.cn 删除。 本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。...

ZackSock
2019/10/25
0
0
Python绘制日历图和热力图

日历热力图 实现某商店2018年10月1号至2019年3月1号期间每一天盈利额(产生5000至30000区间的随机数)的数据可视化。 要求在鼠标放置每个单元格上时显示具体日期和对应数据 import datetime ...

气象学家公众号
07/03
0
0
#乔布简历#计协纳新季福利!乔布简历20元会员卡免费送

#乔布简历#计协纳新季福利!@乔布简历 20元会员卡免费送!活动规则:1)转发本微博/说说@ 三个好友;2)搜索关注“乔布堂”微信公众号,回复“BC016@你的QQ号”;截图发给计协微信公众号:j...

若川
2014/09/22
0
0
第十一届蓝桥第一场省赛题 走方格

走方格 问题描述: 在平面上有一些二维的点阵。这些点的编号就像二维数组的编号一样。从上到下依次为第 1 至第 n 行,从左到右依次为第 1 至第 m 列,每一个点可以用行号和列号来表示。现在有...

osc_kf7nv2km
刚刚
0
0
HTTP/2协议之Stream【原理笔记】

前言 前面三篇介绍了HPPT/2的“连接前言”、“二进制桢”、“头部压缩”。本文从“流及多路复用”、“流状态”、“流量控制”、“流优先级”、“HTTP/2扩展”介绍HTTP/2协议流相关知识。 一、...

瓜农老梁
05/31
0
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部