安卓开发_慕课网_百度地图_刮刮涂层效果

简介: 学习内容来自“慕课网” 很多电商APP中都有刮刮卡活动,刮开涂层,获取刮刮卡内部信息 原理图: 刮刮卡效果:通过画笔画笔来实现,黄色涂层,蓝色涂层,刮动则将两涂层共有的部分去掉,   就是DstOut对应的 效果 MainActivity.

学习内容来自“慕课网”

很多电商APP中都有刮刮卡活动,刮开涂层,获取刮刮卡内部信息

原理图:

刮刮卡效果:通过画笔画笔来实现,黄色涂层,蓝色涂层,刮动则将两涂层共有的部分去掉,   就是DstOut对应的 效果

MainActivity.java

 1 package com.example.gauguaka;
 2 
 3 import android.os.Bundle;
 4 import android.app.Activity;
 5 import android.view.Menu;
 6 
 7 public class MainActivity extends Activity {
 8 
 9     @Override
10     protected void onCreate(Bundle savedInstanceState) {
11         super.onCreate(savedInstanceState);
12         setContentView(R.layout.activity_main);
13     }
14 
15     
16 }

 

新建一个包guaguaka.java 在包中新建类Guaguaka.java 

 

  1 package guaguaka.view;
  2 
  3 import com.example.gauguaka.R;
  4 
  5 import android.content.Context;
  6 import android.graphics.Bitmap;
  7 import android.graphics.Bitmap.Config;
  8 import android.graphics.BitmapFactory;
  9 import android.graphics.Canvas;
 10 import android.graphics.Color;
 11 import android.graphics.Paint;
 12 import android.graphics.Paint.Style;
 13 import android.graphics.Path;
 14 import android.graphics.PorterDuff.Mode;
 15 import android.graphics.PorterDuffXfermode;
 16 import android.graphics.Rect;
 17 import android.graphics.RectF;
 18 import android.util.AttributeSet;
 19 import android.util.Log;
 20 import android.view.MotionEvent;
 21 import android.view.View;
 22 
 23 public class Guaguaka extends View{
 24     //画笔
 25     private Paint moutterpaint;
 26     //记录绘制路径
 27     private Path mpath;
 28     //画布
 29     private Canvas mcanvas;
 30     //图片
 31     private Bitmap mbitmap;
 32     //绘制坐标值
 33     private int mlastx;
 34     private int mlasty;
 35     /*----------------------*/
 36     private Bitmap bitmap;
 37     private Bitmap moutterbitmap;
 38     // 判断遮盖层区域是否消除达到阈值
 39     private volatile boolean mComplete = false;
 40     
 41     
 42     
 43     public Guaguaka(Context context) {
 44         // TODO Auto-generated constructor stub
 45         this(context,null);
 46     }
 47     public Guaguaka(Context context, AttributeSet attrs) {
 48         this(context, attrs,0);
 49         // TODO Auto-generated constructor stub
 50     }
 51     public Guaguaka(Context context, AttributeSet attrs,int defStyle) {
 52         super(context, attrs ,defStyle);
 53         // TODO Auto-generated constructor stub
 54         init();
 55     }
 56     //获得控件的宽度和高度
 57     @Override
 58     protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
 59         // TODO Auto-generated method stub
 60         super.onMeasure(widthMeasureSpec, heightMeasureSpec);
 61         
 62         int width = getMeasuredWidth();
 63         int height = getMeasuredHeight();
 64         // 初始化我们的bitmap
 65         mbitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);
 66         mcanvas = new Canvas(mbitmap);
 67         // 设置绘制path画笔的一些属性
 68         setupOutPaint();
 69         //setUpBackPaint();
 70         //mcanvas.drawColor(Color.parseColor("#c0c0c0"));
 71         //设置刮刮卡框架为圆角
 72         mcanvas.drawRoundRect(new RectF(0, 0, width, height), 30, 30,moutterpaint);
 73         //显示刮刮卡未刮开是的图案
 74         mcanvas.drawBitmap(moutterbitmap, null, new Rect(0, 0, width, height),null);
 75         
 76         
 77     }
 78     //初始化操作
 79     private void init() {
 80         // TODO Auto-generated method stub
 81         moutterpaint = new Paint();
 82         mpath = new Path();
 83         //刮开后的图片(chaji_1是一个茶壶的图片)
 84         bitmap = BitmapFactory.decodeResource(getResources(),R.drawable.chaji_1);    
 85         //刮刮卡未刮时候的图案(fg_guaguaka 是一个刮刮卡字样的图片)
 86         moutterbitmap = BitmapFactory.decodeResource(getResources(),R.drawable.fg_guaguaka);
 87         }
 88     /**
 89      * 设置绘制path画笔的一些属性
 90      */
 91     private void setupOutPaint()
 92     {
 93         //画笔颜色 --红色
 94         moutterpaint.setColor(Color.parseColor("#c0c0c0"));
 95         //锯齿
 96         moutterpaint.setAntiAlias(true);
 97         moutterpaint.setDither(true);
 98         //线条圆角
 99         moutterpaint.setStrokeJoin(Paint.Join.ROUND);
100         moutterpaint.setStrokeCap(Paint.Cap.ROUND);
101         moutterpaint.setStyle(Style.FILL);
102         //画笔宽度
103         moutterpaint.setStrokeWidth(20);
104     }
105     /**
106      * 设置我们绘制获奖信息的画笔属性
107      */
108     
109     //绘制事件
110     @Override
111     public boolean onTouchEvent(MotionEvent event)
112     {
113         int action = event.getAction();
114 
115         int x = (int) event.getX();
116         int y = (int) event.getY();
117 
118         switch (action)
119         {
120         case MotionEvent.ACTION_DOWN://按下
121 
122             mlastx = x;
123             mlasty = y;
124             mpath.moveTo(mlastx, mlasty);
125             break;
126         case MotionEvent.ACTION_MOVE://移动
127 
128             int dx = Math.abs(x - mlastx);
129             int dy = Math.abs(y - mlasty);
130 
131             if (dx > 3 || dy > 3)
132             {
133                 mpath.lineTo(x, y);
134             }
135             //更新坐标
136             mlastx = x;
137             mlasty = y;
138 
139             break;
140         case MotionEvent.ACTION_UP://抬起
141             new Thread(mRunnable).start();// 统计擦除区域任务
142             break;
143         }
144         
145             invalidate();
146         return true;
147 
148     }
149     @Override
150     protected void onDraw(Canvas canvas)
151     {
152             canvas.drawBitmap(bitmap, 0 , 0, null);
153             //注意任务结束,会把一个mComplete设置为true;当为true时,直接展现刮奖区
154             if (!mComplete)
155             {
156             drawPath();
157             canvas.drawBitmap(mbitmap, 0, 0, null);
158             }
159         }
160 
161     private void drawPath()
162     {
163         moutterpaint.setStyle(Style.STROKE);
164         moutterpaint.setXfermode(new PorterDuffXfermode(Mode.DST_OUT));
165         mcanvas.drawPath(mpath, moutterpaint);
166     }
167     /**
168      * 统计擦除区域任务
169      */
170     private Runnable mRunnable = new Runnable()
171     {
172         private int[] mPixels;
173 
174         @Override
175         public void run()
176         {
177 
178             int w = getWidth();
179             int h = getHeight();
180 
181             float wipeArea = 0;
182             float totalArea = w * h;
183 
184             Bitmap bitmap = mbitmap;
185 
186             mPixels = new int[w * h];
187 
188             /**
189              * 拿到所有的像素信息
190              */
191             bitmap.getPixels(mPixels, 0, w, 0, 0, w, h);
192 
193             /**
194              * 遍历统计擦除的区域
195              */
196             for (int i = 0; i < w; i++)
197             {
198                 for (int j = 0; j < h; j++)
199                 {
200                     int index = i + j * w;
201                     if (mPixels[index] == 0)
202                     {
203                         wipeArea++;
204                     }
205                 }
206             }
207             
208             /**
209              * 根据所占百分比,进行一些操作
210              */
211             if (wipeArea > 0 && totalArea > 0)
212             {
213                 int percent = (int) (wipeArea * 100 / totalArea);
214                 Log.e("TAG", percent + "");
215 
216                 if (percent > 70)
217                 {
218                     mComplete = true;
219                     postInvalidate();
220                 }
221             }
222         }
223 
224     };
225 }
Guaguaka.java

 

将布局文件修改:

 1 <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
 2     xmlns:tools="http://schemas.android.com/tools"
 3     android:layout_width="match_parent"
 4     android:layout_height="match_parent"
 5     >
 6 
 7  <guaguaka.view.Guaguaka
 8         android:id="@+id/id_guaguaka"
 9         android:layout_width="300dp"
10         android:layout_height="100dp"
11         android:layout_centerInParent="true"
12         />
13 </RelativeLayout>
activity_main.xml

效果图:

接下来就行效果的优化。

当刮开涂层达到总面积的多少的时候,将全部图案显示出来

首先定义一个布尔值

1 // 判断遮盖层区域是否消除达到阈值
2     private volatile boolean mComplete = false;

添加计算刮开区域面积的线程

 1 private Runnable mRunnable = new Runnable()
 2     {
 3         private int[] mPixels;
 4 
 5         @Override
 6         public void run()
 7         {
 8 
 9             int w = getWidth();
10             int h = getHeight();
11 
12             float wipeArea = 0;
13             float totalArea = w * h;
14 
15             Bitmap bitmap = mbitmap;
16 
17             mPixels = new int[w * h];
18 
19             /**
20              * 拿到所有的像素信息
21              */
22             bitmap.getPixels(mPixels, 0, w, 0, 0, w, h);
23 
24             /**
25              * 遍历统计擦除的区域
26              */
27             for (int i = 0; i < w; i++)
28             {
29                 for (int j = 0; j < h; j++)
30                 {
31                     int index = i + j * w;
32                     if (mPixels[index] == 0)
33                     {
34                         wipeArea++;
35                     }
36                 }
37             }
38             
39             /**
40              * 根据所占百分比,进行一些操作
41              */
42             if (wipeArea > 0 && totalArea > 0)
43             {
44                 int percent = (int) (wipeArea * 100 / totalArea);
45                 Log.e("TAG", percent + "");
46 
47                 if (percent > 70) //如果刮开面积达到70% 则将mComplete布尔值设为true 将全部图案显示出来
48                 {
49                     mComplete = true;
50                     postInvalidate();
51                 }
52             }
53         }
54 
55     };

 

在ACTION_UP,即松开触屏的时候调用

1 case MotionEvent.ACTION_UP://抬起
2             new Thread(mRunnable).start();// 统计擦除区域任务
3             break;

 

任务结束,会把一个mComplete设置为true;当为true时,直接展现刮奖区

 1 @Override
 2     protected void onDraw(Canvas canvas)
 3     {
 4         drawBackText(canvas);
 5 
 6         if (!isComplete)
 7         {
 8             drawPath();
 9             canvas.drawBitmap(mBitmap, 0, 0, null);
10         }
11 
12     }

效果图:

相关文章
|
8天前
|
编解码 Android开发 iOS开发
探索安卓与iOS开发的差异:平台选择对项目成功的影响
在移动应用开发的世界中,安卓和iOS是两大主导力量。本文深入探讨了这两个平台在开发过程中的主要差异,并分析了这些差异如何影响项目的成功。通过对比分析,我们旨在为开发者提供决策时的参考,帮助他们根据项目需求和目标用户群体做出最合适的平台选择。
|
2天前
|
JavaScript 前端开发 Java
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
IT寒冬使APP开发门槛提升,安卓程序员需转型。选项包括:深化Android开发,跟进Google新技术如Kotlin、Jetpack、Flutter及Compose;研究Android底层框架,掌握AOSP;转型Java后端开发,学习Spring Boot等框架;拓展大前端技能,掌握JavaScript、Node.js、Vue.js及特定框架如微信小程序、HarmonyOS;或转向C/C++底层开发,通过音视频项目如FFmpeg积累经验。每条路径都有相应的书籍和技术栈推荐,助你顺利过渡。
12 3
FFmpeg开发笔记(四十七)寒冬下安卓程序员的几个技术转型发展方向
|
6天前
|
Java Android开发 iOS开发
探索安卓与iOS开发的差异:平台选择对项目成功的影响
在移动应用开发的世界中,选择正确的平台是关键。本文通过比较安卓和iOS开发的核心差异,揭示平台选择如何影响应用的性能、用户体验和市场覆盖。我们将深入探讨各自的开发环境、编程语言、用户界面设计原则以及发布流程,以帮助开发者和企业做出明智的决策。
27 9
|
3天前
|
移动开发 开发工具 Android开发
探索安卓与iOS开发的差异:技术选择的影响
【8月更文挑战第17天】 在移动应用开发的广阔天地中,安卓和iOS两大平台各领风骚。本文通过比较这两个平台的编程语言、开发工具及市场策略,揭示了技术选择对开发者和产品成功的重要性。我们将从开发者的视角出发,深入探讨不同平台的技术特性及其对项目实施的具体影响,旨在为即将步入移动开发领域的新手提供一个清晰的指南,同时给予资深开发者新的思考角度。
|
6天前
|
Java 开发工具 Android开发
探索安卓与iOS开发的差异:从新手到专家的旅程
在数字时代的浪潮中,移动应用开发成为了连接世界的桥梁。本文将带你走进安卓与iOS这两大移动操作系统的开发世界,通过比较它们的编程语言、开发工具和环境、用户界面设计以及市场分布等方面,揭示各自的独特之处。无论你是初涉编程的新手,还是寻求进阶的开发者,这篇文章都将为你提供宝贵的洞见,助你在移动应用开发的征途上一帆风顺。
20 5
|
4天前
|
vr&ar Android开发 iOS开发
探索安卓和iOS开发的未来趋势
在移动应用开发的广阔天地里,安卓和iOS两大平台如同双子星座般璀璨夺目。随着技术的不断进步,这两个平台的开发趋势也在悄然发生着变化。本文将带你一探究竟,看看未来安卓和iOS开发将会迎来哪些令人激动的新特性和挑战。让我们一起跟随技术的脚步,开启这场探索之旅吧!
|
5天前
|
移动开发 Java Android开发
安卓与iOS开发:异同探析
在移动应用开发的广阔天地中,安卓和iOS两大平台各自占据半壁江山。本文旨在深入探讨这两个平台在开发环境、编程语言、用户界面设计、性能优化及市场分布等方面的异同,为开发者提供实用的比较视角和决策参考。通过对比分析,我们不仅能更清晰地认识到各平台的特性,还能洞察未来移动开发的可能趋势。
|
6天前
|
Java 开发工具 Android开发
探索Android和iOS开发的差异与挑战
在移动应用开发的广阔天地中,Android和iOS两大平台如同两座高峰,各自拥有独特的风景。本文将深入探讨这两个平台的开发差异,包括编程语言、开发工具、用户界面设计等方面,并分析开发者面临的挑战。无论你是初涉移动应用开发的新手,还是已经在这条路上走了很远的老手,这篇文章都将为你提供新的视角和思考。让我们一起走进这个充满创新与挑战的世界,发现那些隐藏在代码背后的秘密。
|
10天前
|
Java Android开发 Swift
安卓与iOS开发:异同与未来趋势
在移动应用开发的广阔天地中,安卓和iOS两大平台各领风骚。本文将深入浅出地探讨这两大系统在开发过程中的异同点,以及它们如何影响开发者的选择和未来的技术走向。从编程语言到用户界面设计,再到市场分布和盈利模式,我们将逐一剖析,为即将踏入或已在这片热土上耕耘的开发者提供一份清晰的指南。
|
7天前
|
编解码 Android开发 iOS开发
安卓与iOS开发:平台差异下的技术创新之路
在数字时代的浪潮中,移动应用开发如同两股潮流——安卓与iOS,各自携带着独特的技术生态和文化基因。本文将深入探讨这两大平台的开发环境、编程语言和工具的差异,以及它们如何塑造了不同的用户体验和技术趋势。通过比较分析,我们旨在揭示跨平台开发的可能性和挑战,同时探索未来技术创新的方向。让我们一起跟随代码的足迹,穿越安卓的开放草原和iOS的精密园林,发现那些隐藏在平台差异之下的创新机遇。
15 1