zoukankan      html  css  js  c++  java
  • 安卓开发_慕课网_百度地图_刮刮涂层效果

    学习内容来自“慕课网”

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

    效果图:

  • 相关阅读:
    35.python之事件驱动模型
    33.python之操作系统,进程,线程
    VRChat之blender2.8版本设置
    VRChat模型制作及上传总篇(201912)
    linux常用指令
    java基础File的简单使用记录
    java 通过实现Comparable接口使用Collections.sort排序 及 利用set的特性对 list 进行去重
    [转发] java字符串-编码转换-工具类
    ssh服务不能远程时,使用telnet远程登录
    java中List遍历删除元素相关做法和注意事项
  • 原文地址:https://www.cnblogs.com/xqxacm/p/4345147.html
Copyright © 2011-2022 走看看