Android项目刮刮奖详解(四)
前言
上一期我们已经是完成了刮刮卡的基本功能,本期就是给我们的项目增加个功能以及美化一番
目标
- 增加功能 用户刮卡刮到一定程度的时候,清除遮盖层
- 在遮盖层放张图片,增加用户体验
- 增加一个刮完奖回调监听
实现
1.自动消除效果
我们首先来了解一下bitmap的getPixels方法
getPixels(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height)
getPixels()函数把一张图片,从指定的偏移位置(offset),指定的位置(x,y)截取指定的宽高(width,height ),把所得图像的每个像素颜色转为int值,存入pixels。
至于参数stride,查了资料,发现看不太懂,于是便是没有继续深究,我们直接用就是了
我们需要一个线程来完成我们的计算像素,因为计算不能一直在UI线程里面执行,可能会出现卡顿,当用户抬起手指的时候,我们就启动这个计算进程来计算用户所擦除的像素点
本功能有些复杂,要想看得懂,需要了解 UI线程更新View的知识和java中进程部分知识,推荐看一下这篇子进程更新UI
private Runnable mRunnable = new Runnable() {
int[] pixels;
@Override
public void run() {
int w = mBitmap.getWidth();
int h = mBitmap.getHeight();
float wipeArea = 0;//擦除像素点计数,初始为0
float totalArea = w * h;//全部的像素点
pixels = new int[w * h];
/**
* pixels 接收位图颜色值的数组
* offset 写入到pixels[]中的第一个像素索引值
* stride pixels[]中的行间距个数值(必须大于等于位图宽度)。可以为负数
* x 从位图中读取的第一个像素的x坐标值。
* y 从位图中读取的第一个像素的y坐标值
* width 从每一行中读取的像素宽度
* height 读取的行数
*/
Bitmap b = mBitmap;
b.getPixels(pixels, 0, w, 0, 0, w, h);
//for循环查找用户擦除的像素点,为0则是擦除,wipeArea+1
for (int i = 0; i < totalArea; i++) {
if (pixels[i] == 0) {
wipeArea++;
}
}
//
if (wipeArea > 0 && totalArea > 0) {
int percent = (int) (wipeArea * 100 / totalArea);//计算比例
if (percent > 50) {
isClear = true;//isClear是之前声明的全局变量,
postInvalidate();//子进程中调用此方法重绘View
}
}
}
};
上述代码中有个for循环用来记录擦除像素点,有些疑问,因为鸿洋大神用的不一样,鸿洋大神使用的是下面的嵌套循环
for (int i = 0; i < w; i++) {
for (int j = 0; j < h; j++) {
int index = i + j * w;
if (pixels[index] == 0) {
wipeArea++;
}
}
}
之后我们还需要改写代码,首先,是在触摸事件中增加我们对用户抬起手指的操作
case MotionEvent.ACTION_UP:
new Thread(mRunnable).start();
break;
之后,通过isClear这个变量来控制是否画出路径,onDraw方法之中进行这样的修改
protected void onDraw(Canvas canvas) {
canvas.drawText(message,mBitmap.getWidth()/2-mBackground.width()/2,getMeasuredHeight()/2+mBackground.height()/2,messagePaint);
if (!isClear){
drawPath();
canvas.drawBitmap(mBitmap, 0,0, null);
}
}
当canvas写出了文字,之后就不画遮盖层了,这样便是达到了清除遮盖层的效果
这里需要注意一下if中的条件,还要,isClear还得用volatile修饰,通俗的讲就是加了个锁,防止并发出现错误
2.遮盖层绘制图片
可能大家对这个功能很不屑,认为自己之前不是会了吗,其实没有那么简单,我自己尝试的时候都出现了错误,经过搜索资料尝试才达到效果。
先说下我遇到的问题
- 图片只显示一部分
- 画笔清除不了图片,画的时候出现黑色的笔迹
第一个问题,我们可以通过Bitmap的静态方法来解决
public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,boolean filter)
传入一个需要调整大小的bitmap对象,之后,长度和高度,最后一个参数传入true
background = Bitmap.createScaledBitmap(background,width,height,true);//对bitmap进行缩放
第二个问题,因为我们使用的是双缓冲技术绘图,所以,我们需要将遮盖层的图片先绘制在mBitmap中去
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//以获得的宽高创建一个32位的bitmap
mCanvas = new Canvas(mBitmap);
mCanvas.drawBitamap(background,0,0,null);
3.回调接口
public interface onGuaCompleteListener{
void complete();
}
private onGuaCompleteListener mlistener;
public void setGuaCompleteListener(onGuaCompleteListener mlistener) {
this.mlistener = mlistener;
}
之后在onDraw方法里添加回调
protected void onDraw(Canvas canvas) {
Log.d(TAG, "onDraw: 画");
canvas.drawText(message,mBitmap.getWidth()/2-mBackground.width()/2,getMeasuredHeight()/2+mBackground.height()/2,messagePaint);
if (!isClear){
drawPath();
canvas.drawBitmap(mBitmap, 0,0, null);
}else if (mlistener!=null){
mlistener.complete();
}
}
当画到百分之60的时候,就会将isClear的值变为true,同时,就会进入到else if中,回调完成刮奖的接口
我们到MainActivity中设置监听器来监听刮刮卡的完成操作,弹出一个Toast或者是对话框,我这里简单起见就直接弹出一个Toast
GuajiangView mView = (GuajiangView) findViewById(R.id.view);
mView.setGuaCompleteListener(new GuajiangView.onGuaCompleteListener() {
@Override
public void complete() {
Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();
}
});
测试图

Android项目刮刮奖详解(四)的更多相关文章
- Android项目刮刮奖详解(二)
Android项目刮刮奖详解(一) 前言 上期我们简单地实现了一个画板的功能,用户可以在上面乱写乱画,其实,刮刮奖也是如此,用户刮奖的时候也是乱写乱画的. 刮刮奖原理 一共有两层画布,底层画布存放中奖 ...
- Android项目刮刮奖详解扩展篇——开源刮刮奖View的制作
Android项目刮刮奖详解(四) 前言 我们已经成功实现了刮刮奖的功能了,本期是扩展篇,我们把这个View直接定义成开源控件,发布到JitPack上,以后有需要也可以直接使用,关于自定义控件的知识, ...
- Android项目刮刮奖详解(三)
Android项目刮刮奖详解(二) 前言 上一期我们已经实现了一个简易的刮刮卡功能,这一期我们来将其完善一下 目标 将刮刮奖的宽高改为合适高度 将刮刮奖位置居中 将信息层的图片换成文字(重点) 实现 ...
- Drawable实战解析:Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解 (旧版本 | 仅作参考)
. 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...
- Android高效率编码-第三方SDK详解系列(二)——Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能
Android高效率编码-第三方SDK详解系列(二)--Bmob后端云开发,实现登录注册,更改资料,修改密码,邮箱验证,上传,下载,推送消息,缩略图加载等功能 我的本意是第二篇写Mob的shareSD ...
- Android高效率编码-第三方SDK详解系列(一)——百度地图,绘制,覆盖物,导航,定位,细腻分解!
Android高效率编码-第三方SDK详解系列(一)--百度地图,绘制,覆盖物,导航,定位,细腻分解! 这是一个系列,但是我也不确定具体会更新多少期,最近很忙,主要还是效率的问题,所以一些有效的东西还 ...
- Android XML shape 标签使用详解(apk瘦身,减少内存好帮手)
Android XML shape 标签使用详解 一个android开发者肯定懂得使用 xml 定义一个 Drawable,比如定义一个 rect 或者 circle 作为一个 View 的背景. ...
- 【Android 应用开发】Ubuntu 下 Android Studio 开发工具使用详解
. 基本上可以导入项目开始使用了 ... . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21035637 ...
随机推荐
- Java后期拓展(一)之Redis
1.NoSQL数据库简介 2.Redis的介绍及安装启动 3.Redis的五大数据类型 4.Redis的相关配置 5.Redis的Java客户端Jedis 6.Redis的事务 7.Redis的持久化 ...
- java中List<Map<String, Object>>关于null的判断
List<Map<String, Object>> selectTmFileInfo = fileInfoService.selectTmFileInfoByToken(cTo ...
- web测试实践——day01
一.任务进展情况 主要是找寻网站的bug,分析bug的严重程度.同时找了本专业的同学进行博客园系统的使用. 二.存在的问题 由于上线的网站做的比较完善,导致找寻bug比较困难. 三.解决方法 对此我们 ...
- C语言面试题分类->指针
有关指针的经典面试题 C语言为何如此长寿并实用?C++为什么有那么多精彩?指针可以说是C/C++中的灵魂所在,虽然早期中pascal也有指针,但是和C/C++比起来不是一个级别的.今天为大家深入浅出的 ...
- 【.NET Core微服务实战-统一身份认证】开篇及目录索引
简介 学习.NETCORE也有1年多时间了,发现.NETCORE项目实战系列教程很少,都是介绍开源项目或基础教程,对于那些观望的朋友不能形成很好的学习思路,遇到问题怕无法得到解决而不敢再实际项目中 ...
- 【RL-TCPnet网络教程】第32章 RL-TCPnet之Telnet服务器
第32章 RL-TCPnet之Telnet服务器 本章节为大家讲解RL-TCPnet的Telnet应用,学习本章节前,务必要优先学习第31章的Telnet基础知识.有了这些基础知识之后,再搞 ...
- HTTP/2 资料汇总
随着今年 5 月 14 日 HTTP/2 协议正式版的发布,越来越多的网站开始部署 HTTP/2 了.我对 HTTP 协议一直都比较有兴趣,本文汇总一些关于 HTTP/2 的资料以及我写过的文章,会持 ...
- RabbitMQ进程结构分析与性能调优
RabbitMQ是一个流行的开源消息队列系统,是AMQP(高级消息队列协议)标准的实现,由以高性能.健壮.可伸缩性出名的Erlang语言开发,并继承了这些优点.业界有较多项目使用RabbitMQ,包括 ...
- [Swift]LeetCode105. 从前序与中序遍历序列构造二叉树 | Construct Binary Tree from Preorder and Inorder Traversal
Given preorder and inorder traversal of a tree, construct the binary tree. Note:You may assume that ...
- [SQL]LeetCode596. 超过5名学生的课 | Classes More Than 5 Students
SQL架构 Create table If Not Exists courses (student varchar(), )) Truncate table courses insert into c ...