Android Studio实现刮刮卡效果

代码和刮刮乐图片参考网络
实现效果
在这里插入图片描述
在这里插入图片描述

MainActivity

import android.app.Activity;
import android.os.Bundle;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);}
}

ScratchCardView

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class ScratchCardView extends View {//类成员变量private Paint mPaint;//画笔private Path mPath;//手指滑动的路径private Canvas mCanvas;//临时画布private Bitmap mBackGroundBitmap;//未刮奖前背景private Bitmap mForeGroundBitmap;//前景图(灰色)private int mLastX, mLastY;//滑动结束点的坐标public ScratchCardView(Context context) {this(context, null);}public ScratchCardView(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ScratchCardView(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}/*** 初始化操作*/private void init() {mPaint = new Paint();//初始化画笔mPaint.setAlpha(0);//设置alpha不透明度,范围为0~255mPaint.setAntiAlias(true);//消除锯齿边,给画笔设置平滑的属性mPaint.setStyle(Paint.Style.STROKE);//描边效果mPaint.setStrokeCap(Paint.Cap.ROUND);//圆角效果mPaint.setStrokeJoin(Paint.Join.ROUND);//设置圆角mPaint.setStrokeWidth(20);//设置画笔宽度mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));//设置图层混合模式mPath = new Path();// 实例化路径//未刮奖前背景 图片资源转化为BitmapmBackGroundBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.background);//创建一个和背景图大小一致的Bitmap对象作为装载画布mForeGroundBitmap = Bitmap.createBitmap(mBackGroundBitmap.getWidth(), mBackGroundBitmap.getHeight(), Config.ARGB_8888);//与Canvas进行绑定  //画涂层的画布,传一个Bitmap进去,所画的信息都存在Bitmap上mCanvas = new Canvas(mForeGroundBitmap);//涂成灰色mCanvas.drawColor(Color.BLUE);}@Overrideprotected void onDraw(Canvas canvas) {//先把底层的画画到View的画布上canvas.drawBitmap(mBackGroundBitmap, 0, 0, null);//绘制前景层canvas.drawBitmap(mForeGroundBitmap, 0, 0, null);}/*** 手指滑动事件处理,把手指移动的轨迹保存在Path中.* 不停的移动,就不停的回调View的更新UI的方法:invalidate();*/@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {//当用户按下屏幕时,会执行MotionEvent.ACTION_DOWN的case分支,// 记录下当前的坐标,并将路径(Path)移动到该点case MotionEvent.ACTION_DOWN:mLastX = (int) event.getX();mLastY = (int) event.getY();mPath.moveTo(mLastX, mLastY);break;//当用户在屏幕上滑动时,会执行MotionEvent.ACTION_MOVE的case分支,// 记录下当前的坐标,并将路径绘制到该点case MotionEvent.ACTION_MOVE:mLastX = (int) event.getX();mLastY = (int) event.getY();mPath.lineTo(mLastX, mLastY);break;//当用户松开屏幕时,会执行MotionEvent.ACTION_UP的case分支,不做任何操作。case MotionEvent.ACTION_UP:break;default:break;}mCanvas.drawPath(mPath, mPaint);//将路径绘制到画布上invalidate();//调用invalidate()方法刷新视图return true;//表示已经处理了触摸事件}
}

ScratchCardView2

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;public class ScratchCardView2 extends View {//处理文字private String mText = "恭喜您中奖啦!!";//刮奖文本信息private Paint mTextPaint;//文字画笔private Rect mRect;//用于表示坐标系中的一块矩形区域//处理图层private Paint mForePaint;//画笔private Path mPath;//手指滑动的路径private Bitmap mBitmap;//加载资源文件private Canvas mForeCanvas;//前景图Canvasprivate Bitmap mForeBitmap;//前景图Bitmap//记录位置private int mLastX;private int mLastY;private volatile boolean isClear;//标志是否被清除public ScratchCardView2(Context context) {this(context, null);}public ScratchCardView2(Context context, AttributeSet attrs) {this(context, attrs, 0);}public ScratchCardView2(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);init();}private void init() {mRect = new Rect();//实例化矩形区域mPath = new Path();//实例化画笔的路径//文字画笔mTextPaint = new Paint();//初始化画笔mTextPaint.setAntiAlias(true);//消除锯齿边,给画笔设置平滑的属性mTextPaint.setColor(Color.BLACK);//文字颜色mTextPaint.setStyle(Paint.Style.FILL_AND_STROKE);//描边效果mTextPaint.setTextSize(50);//字体大小//用于测量文本边界的方法。这个方法接受四个参数://mText 是要测量的文本字符串,0 是文本开始的位置,mText.length() 是文本的长度,mRect 是用于存储测量结果的矩形。mTextPaint.getTextBounds(mText, 0, mText.length(), mRect);//擦除画笔mForePaint = new Paint();mForePaint.setAntiAlias(true);  //消除锯齿边,给画笔设置平滑的属性mForePaint.setAlpha(0); //设置alpha不透明度,范围为0~255mForePaint.setStrokeCap(Paint.Cap.ROUND);//圆角效果mForePaint.setStrokeJoin(Paint.Join.ROUND);//设置圆角mForePaint.setStyle(Paint.Style.STROKE);//描边效果mForePaint.setStrokeWidth(50);//设置画笔宽度mForePaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));//设置图层混合模式//在相交时利用源图像的透明度来改变目标图像的透明度和饱和度的,也就是当源图像透明度为0时,目标图像完全不显示//通过资源文件创建Bitmap对象  图片资源转化为BitmapmBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.background);//创建一个和背景图大小一致的Bitmap对象作为装载画布mForeBitmap = Bitmap.createBitmap(mBitmap.getWidth(), mBitmap.getHeight(), Bitmap.Config.ARGB_8888);//双缓冲,装载画布//与Canvas进行绑定  //画涂层的画布,传一个Bitmap进去,所画的信息都存在Bitmap上mForeCanvas = new Canvas(mForeBitmap);//将前景图画到View的画布上mForeCanvas.drawBitmap(mBitmap, 0, 0, null);}@Overrideprotected void onDraw(Canvas canvas) {//canvas.drawText()方法绘制文本,这个方法接收四个参数:// 要绘制的文本字符串 mText,// 文本的水平位置 mForeBitmap.getWidth() / 2 - mRect.width() / 2,// 文本的垂直位置 mForeBitmap.getHeight() / 2 + mRect.height() / 2,// 以及用于绘制文本的画笔对象 mTextPaintcanvas.drawText(mText, mForeBitmap.getWidth() / 2 - mRect.width() / 2, mForeBitmap.getHeight() / 2 + mRect.height() / 2, mTextPaint);//如果 isClear 为 false,则使用 canvas.drawBitmap() 方法绘制位图。//方法接收三个参数:要绘制的位图对象 mForeBitmap,位图在画布上的水平位置 0,位图在画布上的垂直位置 0if (!isClear) {canvas.drawBitmap(mForeBitmap, 0, 0, null);}}@Overridepublic boolean onTouchEvent(MotionEvent event) {switch (event.getAction()) {//当用户按下屏幕时,会执行MotionEvent.ACTION_DOWN的case分支,// 记录下当前的坐标,并将路径(Path)移动到该点case MotionEvent.ACTION_DOWN:mLastX = (int) event.getX();mLastY = (int) event.getY();mPath.moveTo(mLastX, mLastY);break;//当用户在屏幕上滑动时,会执行MotionEvent.ACTION_MOVE的case分支,// 记录下当前的坐标,并将路径绘制到该点case MotionEvent.ACTION_MOVE:mLastX = (int) event.getX();mLastY = (int) event.getY();mPath.lineTo(mLastX, mLastY);break;//当用户松开屏幕时,会执行MotionEvent.ACTION_UP的case分支,不做任何操作。case MotionEvent.ACTION_UP:new Thread(mRunnable).start();break;default:break;}mForeCanvas.drawPath(mPath, mForePaint);//将路径绘制到画布上invalidate();//调用invalidate()方法刷新视图return true;//表示已经处理了触摸事件}/*** 开启子线程计算被擦除的像素点*/private Runnable mRunnable = new Runnable() {int[] pixels;// 这段代码的作用是计算位图中透明像素的擦拭面积,// 并根据擦拭面积占总面积的比例判断是否达到清除条件,如果达到则刷新视图。@Overridepublic void run() {//获取mForeBitmap的宽和高int w = mForeBitmap.getWidth();int h = mForeBitmap.getHeight();float wipeArea = 0;//擦拭面积float totalArea = w * h;//总面积pixels = new int[w * h];/*** pixels      接收位图颜色值的数组* offset      写入到pixels[]中的第一个像素索引值* stride      pixels[]中的行间距个数值(必须大于等于位图宽度)。可以为负数* x           从位图中读取的第一个像素的x坐标值。* y           从位图中读取的第一个像素的y坐标值* width      从每一行中读取的像素宽度* height    读取的行数*///获取位图像素数据存储到数组中,mForeBitmap 是一个位图对象,//pixels 是一个用于存储像素数据的数组。w 和 h 分别表示要获取的像素数据的宽度和高度。这个方法将指定区域的位图像素数据存储到 pixels 数组中。mForeBitmap.getPixels(pixels, 0, w, 0, 0, w, h);//使用两层循环遍历位图的每个像素for (int i = 0; i < w; i++) {for (int j = 0; j < h; j++) {int index = i + j * w;//判断像素的颜色值是否为0(即透明像素),如果是,则将擦拭面积wipeArea加1。if (pixels[index] == 0) {wipeArea++;}}}//在循环结束后,通过判断擦拭面积和总面积是否大于0,计算出擦拭面积占总面积的百分比。//如果擦拭面积百分比大于50%,则将变量isClear置为true,表示达到了清除条件。//最后调用postInvalidate()方法刷新视图。if (wipeArea > 0 && totalArea > 0) {int percent = (int) (wipeArea * 100 / totalArea);if (percent > 50) {isClear = true;postInvalidate();}}}};
}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"><com.example.guaguale.ScratchCardView2android:id="@+id/scratchCardView"android:layout_width="200dp"android:layout_height="200dp"android:layout_centerVertical="true"android:layout_centerHorizontal="true" />
</RelativeLayout>

遮盖图
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/29950.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ruoyi-cloud微服务新建子模块

ruoyi-cloud微服务新建子模块 1、复制system模块 直接复制 modules下面已有的system模块&#xff0c;改名为 test 2、在modules下的 pom.xml文件中添加子模块 3、进入 test模块修改 pom.xml 把原有的system 修改成test 4、修改对应的包名、目录名和启动应用程序为test 5、修…

大学生口才培训需求分析

标题&#xff1a;大学生口才培训需求分析 摘要&#xff1a; 本论文旨在分析大学生口才培训的需求&#xff0c;通过对大学生口才培训的重要性、现状和挑战进行研究&#xff0c;并结合相关理论和实践经验&#xff0c;提出相应的培训需求和解决方案。通过本论文的研究&#xff0c…

介绍另外一个容器技术, Apptainer

一说到容器&#xff0c;我们往往会脱口而出&#xff0c; Docker&#xff0c; 实际上Docker 仅仅是Linux 容器化的一种&#xff0c; 今天介绍的Apptainer 就是另外一种容器技术。 那么Apptainer 具体是一个什么东西呢&#xff1f; 跟Docker 有什么区别呢&#xff1f; 首先&#…

【HarmonyOS】Java如何引用外部jar包

【关键字】 Java、引用jar包​ 【写在前面】 使用API6和API7开发HarmonyOS应用时&#xff0c;因为应用中只能引用SDK中开放的功能接口&#xff0c;但是部分jdk自带的接口功能在SDK中并未封装&#xff0c;要想在工程中使用jdk开放的接口功能&#xff0c;需要将jdk中的jar包通过…

【TS第三讲】完善TS开发环境

文章目录 &#x1f31f; 写在前面&#x1f31f; ts-node&#x1f31f; nodemon&#x1f31f; nodemon文件类型&#x1f31f; nodemon文件范围&#x1f31f; 写在最后 &#x1f31f; 写在前面 &#x1f525;探索TypeScript世界&#xff0c;驭Vue3Ts潮流&#xff0c;开启前端之旅…

STM32--综述

文章目录 前言STM32简介STM32F103C8T6系统结构Keil软件安装注意事项新建工程操作流程 前言 本专栏将学习B站江协科技的STM32入门教程&#xff0c;通过自身理解和对老师的总结所写的博客专栏。 STM32简介 STM32是意法半导体&#xff08;STMicroelectronics&#xff09;公司推…

intelJ IDEA\PHPStorm \WebStorm\PyCharm 通过ssh连接远程Mysql\Postgresql等数据库

最容易出错的地方是在general面板下的host&#xff0c;不应该填真实的host地址&#xff0c;而应该填localhost或者127.0.0.1 具体操作步骤见下图

Shopify平台Fulfillment业务模块升级

上图是销售订单、发货单与配送之间的关系图&#xff0c;销售订单可以创建多个发货单&#xff0c;多个发货单(不同销售订单)可以合并在一个配送订单进行发货 接口请求错误记录: 1. The api_client does not have the required permission(s). 2. Required parameter missing or…

特殊符号的制作 台风 示例 使用第三方工具 Photoshop 地理信息系统空间分析实验教程 第三版

特殊符号的制作 首先这是一个含有字符的&#xff0c;使用arcgis自带的符号编辑器制作比较困难。所以我们准备采用Adobe Photoshop 来进行制作符号&#xff0c;然后直接导入符号的图片文件作为符号 我们打开ps&#xff0c;根据上面的图片的像素长宽比&#xff0c;设定合适的高度…

FastAPI和Flask:构建RESTful API的比较分析

Python 是一种功能强大的编程语言&#xff0c;广泛应用于 Web 开发领域。FastAPI 和 Flask 是 Python Web 开发中最受欢迎的两个框架。本文将对 FastAPI 和 Flask 进行综合对比&#xff0c;探讨它们在语法和表达能力、生态系统和社区支持、性能和扩展性、开发工具和调试支持、安…

【springboot项目】在idea中启动报错合集

一、IDEA中报错 “Error running ‘Application‘: Command line is too long.“ 的解决办法 报错详情&#xff1a; Error running Application: Command line is too long.Shorten command line for Application or also for Spring Boot default configuration.报错原因&am…

Linux 目录结构

初学Linux&#xff0c;首先需要弄清Linux 标准目录结构 / root --- 启动Linux时使用的一些核心文件。如操作系统内核、引导程序Grub等。home --- 存储普通用户的个人文件 ftp --- 用户所有服务httpdsambauser1user2bin --- 系统启动时需要的执行文件&#xff08;二进制&#x…

【TypeScript】中关于 { 声明合并 } 的使用及注意事项

概念&#xff1a; 在TS中&#xff0c;如果定义了多个相同命名的函数&#xff0c;接口或者class 类&#xff0c;那么它们会自动合并成一个类型 函数的合并&#xff1a; 前面章节讲解的函数重载就是使用了定义多个函数的类型进行合并&#xff1a; function reverse(x: number):…

在家构建您的迷你聊天Chat gpt

推荐&#xff1a;使用 NSDT场景编辑器 助你快速搭建可编辑的3D应用场景 什么是指令遵循模型&#xff1f; 语言模型是机器学习模型&#xff0c;可以根据句子的前一个单词预测单词概率。如果我们向模型请求下一个单词&#xff0c;并将其递减地反馈给模型以请求更多单词&#xff…

css3背景渐变

1.线性渐变 <style>.box {width: 200px;height: 200px;border: 1px solid black;float: left;margin-left: 50px;}.box1 {background-image: linear-gradient(green, yellow, red);}/* 右上 */.box2 {background-image: linear-gradient(to right top, green, yellow, re…

【前端 | CSS】aligin-items与aligin-content的区别

align-items 描述 CSS align-items 属性将所有直接子节点上的 align-self 值设置为一个组。align-self 属性设置项目在其包含块中在交叉轴方向上的对齐方式 align-items是针对每一个子项起作用&#xff0c;它的基本单位是每一个子项&#xff0c;在所有情况下都有效果&…

js案例:1.简单计算器

目录 一.效果图 二.实现思路 整体思路 ​ 1.关键是dom操作 ​ 2.设置点击事件 3.数据类型的隐式转换和赋值 三.完整代码 一.效果图 二.实现思路 整体思路 1.关键是dom操作 通过 document.getElementById(id) 获取html中的dom元素 每一个html标签都是一个对象&…

java【native关键字】

描述&#xff1a; native只能修饰方法&#xff0c;表示这个方法的方法体代码不是用java语言实现的&#xff0c;而是由c/c语言编写的。但是对于java程序员来说&#xff0c;可以当作java的方法一样正常去调用它&#xff0c;或者子类重写它 语法&#xff1a; 用在方法的返回值类…

【腾讯云 Cloud Studio 实战训练营】一个新的趋势已来

写在前面&#xff1a;博主是一只经过实战开发历练后投身培训事业的“小山猪”&#xff0c;昵称取自动画片《狮子王》中的“彭彭”&#xff0c;总是以乐观、积极的心态对待周边的事物。本人的技术路线从Java全栈工程师一路奔向大数据开发、数据挖掘领域&#xff0c;如今终有小成…

二分法的应用

文章目录 什么是二分法&#x1f3ae;二分查找的优先级二分查找的步骤&#x1f4a5;图解演示&#x1f9e9; 代码演示&#x1fad5;python程序实现&#x1f408;‍⬛C程序实现&#x1f415;‍&#x1f9ba;C程序实现&#x1f42f;Java程序实现&#x1f433; 非常规类二分查找&…