概述:

很早之前就想研究一下Android中的涂鸦,其实也说不上是研究了,毕竟都是一些相对比较简单的知识点。下面就对基于画布(Canvas)和触摸事件(onTouchEvent)来实现涂鸦和刮刮乐。

参考:

http://blog.csdn.net/lmj623565791/article/details/40162163

此人的博客的确很好,想学习的同学也可以去参考一下这个大牛的其他博客。

http://blog.csdn.net/t12x3456/article/details/10432935

示例分析:

以下是两个简单的入门示例:涂鸦技术和刮刮乐的一些简单分析和效果展示。

1.涂鸦

思路分析及代码展示

学习过Canvas的同学应该都知道我们可以通过在一个View上覆盖一个canvas,并实现View的onTouchEvent方法就可以在Canvas上留下触摸屏幕时的轨迹,对于轨迹的记录还有一个类需要去了解——Path。关于Canvas更多的知识请点击这里查看。

Android在绘制界面的时候会获得布局中控件的大小、位置等参数之后再去绘制。而这里我们只是通过onMeasure和onDraw来绘制,没有用到onLayout是因为这里只有一个控件,没有太多动态布局需要处理。对于路径的记录则需要onTouchEvent实现。

测量大小:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = getMeasuredWidth();int height = getMeasuredHeight();// 初始化bitmapmBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);mCanvas = new Canvas(mBitmap);}

绘制:

protected void onDraw(Canvas canvas) {drawPath();canvas.drawBitmap(mBitmap, 0, 0, null);}

路径绘制:

我们通过Path保存我们触摸的路径轨迹。如下:

private void drawPath() {mFingerPaint.setStyle(Paint.Style.STROKE);mCanvas.drawPath(mPath, mFingerPaint);}

触摸事件:

对于触摸事件有一个非常重要而且不可忽视的类就是MotionEvent。它有以下三个常用的动作事件:

1.MotionEvent.ACTION_DOWN // 触摸按下时

2.MotionEvent.ACTION_MOVE // 触摸在移动过程中

3.MotionEvent.ACTION_UP   // 触摸离开时

下面就看看onTouchEvent事件的实现过程:

public boolean onTouchEvent(MotionEvent event) {int action = event.getAction();int x = (int) event.getX();int y = (int) event.getY();switch (action) {case MotionEvent.ACTION_DOWN:actionMotionEventDown(x, y);break;case MotionEvent.ACTION_MOVE:actionMotionEventMove(x, y);break;}invalidate();return true;}

上面的代码中,我们在按下的时候实现了按下的逻辑,在手指在屏幕上移动的时候实现了Move的逻辑。 还有别忘了invalidate()。invalidate()函数的主要作用是请求View树进行重绘,如果你不去调用它,结果就是什么事情都不会发生。

效果图

2.刮刮乐

思路分析及代码展示

分析:其实刮刮乐的实现思路跟涂鸦很像,都是在一块地方瞎画,并留下痕迹(说笑了,不过也不无道理。^_^)。不过有一点不同的就是我们在刮刮乐的绘制过程中画笔经过的地方,是变成了透明的了。这里你可能会说,那简单了,不就是要我去覆盖两层图片,在去绘制触摸路径,只是触摸路径的颜色是透明的。真的是这样的么?你可以试一试。当然,这样是行不通的,关于实践的最终效果大家可以自行尝试。这里的关键点在于我们要把上面的蒙层擦除且保留下面的底层。这里就用到了图形混合技术了。

图形混合技术一听名称是不是就是感觉很高深,不过的确是很牛的技术,不过Java已经给我们封装好了,我们只要知道怎么使用即可,而使用它则就不那么艰难了。

关于图形混合的详细描述,大家可以参考这里,我就不重复制造轮子了。不过我还是要简单介绍一下Xfermode三个子类下的一个:PorterDuffXfermode。这是一个非常强大的转换模式,使用它,可以使用图像合成的16条Porter-Duff规则的任意一条来控制Paint如何与已有的Canvas图像进行交互。

Porter-Duff规则如下:

PorterDuff.Mode为枚举类,一共有16个枚举值:
1.PorterDuff.Mode.CLEAR
  所绘制不会提交到画布上。
2.PorterDuff.Mode.SRC
   显示上层绘制图片
3.PorterDuff.Mode.DST
  显示下层绘制图片
4.PorterDuff.Mode.SRC_OVER
  正常绘制显示,上下层绘制叠盖。
5.PorterDuff.Mode.DST_OVER
  上下层都显示。下层居上显示。
6.PorterDuff.Mode.SRC_IN
   取两层绘制交集。显示上层。
7.PorterDuff.Mode.DST_IN
  取两层绘制交集。显示下层。
8.PorterDuff.Mode.SRC_OUT
 取上层绘制非交集部分。
9.PorterDuff.Mode.DST_OUT
 取下层绘制非交集部分。
10.PorterDuff.Mode.SRC_ATOP
 取下层非交集部分与上层交集部分
11.PorterDuff.Mode.DST_ATOP
 取上层非交集部分与下层交集部分
12.PorterDuff.Mode.XOR
  异或:去除两图层交集部分
13.PorterDuff.Mode.DARKEN
  取两图层全部区域,交集部分颜色加深
14.PorterDuff.Mode.LIGHTEN
  取两图层全部,点亮交集部分颜色
15.PorterDuff.Mode.MULTIPLY
  取两图层交集部分叠加后颜色
16.PorterDuff.Mode.SCREEN
  取两图层全部区域,交集部分变为透明色

我们需要的正是:DstOut这一条。代码中我们是这样实现的:

private void drawPath() {mFingerPaint.setStyle(Paint.Style.STROKE);// 设置两张图片相交时的模式(取下层绘制非交集部分)mFingerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));mCanvas.drawPath(mPath, mFingerPaint);}

测量和绘制过程如下:

@Overrideprotected void onDraw(Canvas canvas) {canvas.drawText(mText, getWidth() / 2 - mTextBound.width() / 2, getHeight() / 2 + mTextBound.height() / 2, mBackPint);if (!isComplete) {drawPath();canvas.drawBitmap(mBitmap, 0, 0, null);}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = getMeasuredWidth();int height = getMeasuredHeight();// 初始化bitmapmBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);mCanvas = new Canvas(mBitmap);// 绘制遮盖层mFingerPaint.setStyle(Paint.Style.FILL);mCanvas.drawRoundRect(new RectF(0, 0, width, height), 30, 30, mFingerPaint);mCanvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.mask), null, new RectF(0, 0, width, height), null);}

此外还有一篇也是使用了此技术的博客,点击 这里进行查看。

效果图

源码下载:

http://download.csdn.net/detail/u013761665/8737527

Android涂鸦技术及刮刮乐示例分析相关推荐

  1. Android实现 刮刮乐效果

    一.实现原理与所需技术 Android刮刮乐效果的实现,自定义view,绘制出中奖信息,将一张图片绘制在中奖信息的上层,通过onTouchEvent监听用户手势,通过path记录绘制轨迹,设置绘制方式 ...

  2. 【自定义控件】Android仿刮刮乐|刮刮卡|橡皮擦效果

    背景:需要实线一个类似刮刮乐的擦一擦效果,要求是在图片上覆盖半透明蒙层,蒙层支持手势擦除(类似橡皮擦). 思路:使用自定义View在onDraw时进行绘制,绘制模式选择混合模式(叠加变透明). 示例: ...

  3. android 实现刮刮乐刮奖效果

    在做电商类产品时,经常会有一些活动需求,如抽奖,抽奖的一种方式就是刮刮乐,这次的内容是利用重写View的方式实现刮刮乐的效果. 思路:利用Bitmap做刮奖区的蒙版,利用paint将手指触摸过的区域置 ...

  4. Android 撕衣服(刮刮乐游戏)

    项目简单介绍: 该项目为撕衣服,相似刮刮乐游戏 具体介绍: 用户启动项目后.载入一张图片,当用户点击图片的时候,点击的一片区域就会消失.从而显示出在这张图片以下的图片 这个小游戏相似与刮奖一样,刮开涂 ...

  5. 【Android界面实现】使用Canvas对象实现“刮刮乐”效果

    在淘宝.京东等电商举办活动的时候,经常可以看到在移动客户端推出的各种刮奖活动,而这种活动也受到了很多人的喜爱.从客户端的体验来说,这种效果应该是通过网页来实现的,那么,我们使用Android的自带控件 ...

  6. android刮刮乐游戏布局,Android studio实现刮刮乐的方法

    本文实例为大家分享了android studio实现刮刮乐的具体代码,供大家参考,具体内容如下 mainactivity public class mainactivity extends appco ...

  7. Android自定义view实现刮刮乐

    已经有两个月没有更新博客了,其实这篇文章我早在两个月前就写好了,一直保存在草稿箱里没有发布出来.原因是有一些原理性的东西还没了解清楚,最近抽时间研究了一下混合模式,终于也理解了刮刮乐是怎么实现的,所以 ...

  8. Android实现彩票刮刮乐效果

    在一些应用,比如支付宝.天猫app我们经常能够看到一些刮奖的功能效果,通过用户手指滑动模拟出"刮刮乐"刮奖的视觉效果,让用户有一种刮彩票时候那种"爽"的感觉. ...

  9. 刮刮乐html5效果擦除,利用HTML5的画布Canvas实现刮刮卡效果

    先给大家展示效果: 你玩过刮刮卡么?一不小心可以中奖的那种.今天我给大家分享一个基于HTML5技术实现的刮刮卡效果,在PC上只需按住鼠标,在手机上你只需按住指头,轻轻刮去图层就可以模拟真实的刮奖效果. ...

最新文章

  1. iptables防DDOS***和CC***设置
  2. 360全景html插件,jquery实现360度全景展示特效插件
  3. memcached+magent实现memcached集群
  4. Android 图片放大缩小
  5. 被request.getLocalAddr()苦闷了很久
  6. Java springboot访问templates的html和静态资源
  7. 抖音做综艺,差点意思
  8. java编程详解 pdf_Java高并发编程详解:多线程与架构设计 高清pdf扫描版[154MB]
  9. 数据库编程之嵌入式SQL
  10. linux在拥有/etc/xdg的自启动方式
  11. Unity-存档与读档
  12. Aocoda-RCF7/F7 MINI飞控无法解锁的疑难杂症-使用 Betaflight 10.8.0调参软件地面站刷写固件以及AOCODAF722MINI 配置文件
  13. tx2 can通信之开机自动加载can模块
  14. winrar 去广告_winRAR去广告版软件安装教程
  15. Android横竖屏屏幕方向设置
  16. 做了个多语种网站 不能被GOOGLE,yahoo收录,baidu可以收录 终于找到问题
  17. 一种喷涂有可吸收电磁波的水性油漆的飞机外壳
  18. python使用继承开发动物和狗
  19. 集成平台、大数据平台、数据治理平台,医院信息科应该怎么选?
  20. 《富爸爸、穷爸爸》精华摘要

热门文章

  1. C++ Primer 5th笔记(2)chapter 2变量和基本类型:constexpr 、auto、类型别名、decltype
  2. React中的路由react-router
  3. 栈——用链表实现栈操作
  4. create_softLink.sh
  5. android密码解锁/指纹解锁返回的authToken深度解剖
  6. [ARM异常]-图解armv7/armv8的异常向量表和基地址
  7. 人工智能-基于U^2-Net的肖像画生成算法
  8. etcd - 一个分布式一致性键值存储系统
  9. /GS 编译选项,_security_cookie,软件强制DEP
  10. 2020-10-27(原码,反码,补码的产生)