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

学习内容来自“慕课网”

很多电商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     }

效果图:

posted @ 2014-12-17 20:31  听着music睡  阅读(501)  评论(0编辑  收藏  举报