Android实现刮刮乐示例分析

微信公众号有很多都做刮刮乐的活动,本文就实现了刮刮乐的效果,具体代码如下:

首先要做一个类似橡皮擦的东西吧,然后才能把纸上的笔迹擦除

/**
   * FileName: SplashActivity.java
   *
   * @desc 橡皮擦功能,类似刮刮乐效果
   * @author HTP
   * @Date 20140311
   * @version 1.00
   */
  public class Text_Rubbler extends TextView { 

    private float TOUCH_TOLERANCE; // 填充距离,使线条更自然,柔和,值越小,越柔和。 

    // private final int bgColor;
    // 位图
    private Bitmap mBitmap;
    // 画布
    private Canvas mCanvas;
    // 画笔
    private Paint mPaint;
    private Path mPath;
    private float mX, mY; 

    private boolean isDraw = false; 

    public Text_Rubbler(Context context) {
      /**
       * @param context 上下文
       */
      super(context); 

    } 

    public Text_Rubbler(Context context, AttributeSet attrs, int defStyle) {
      super(context, attrs, defStyle);
      // bgColor =
      // attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android",
      // "textColor", 0xFFFFFF);
      // System.out.println("Color:"+bgColor);
    } 

    public Text_Rubbler(Context context, AttributeSet attrs) {
      super(context, attrs);
      // bgColor =
      // attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android",
      // "textColor", 0xFFFFFF);
      // System.out.println(bgColor);
      // System.out.println(attrs.getAttributeValue("http://schemas.android.com/apk/res/android",
      // "layout_width"));
    } 

    @Override
    protected void onDraw(Canvas canvas) {
      super.onDraw(canvas);
      if (isDraw) { 

        mCanvas.drawPath(mPath, mPaint);
        // mCanvas.drawPoint(mX, mY, mPaint);
        canvas.drawBitmap(mBitmap, 0, 0, null);
      }
    } 

    /**
     * 开启檫除功能
     *
     * @param bgColor
     *      覆盖的背景颜色
     * @param paintStrokeWidth
     *      触点(橡皮)宽度
     * @param touchTolerance
     *      填充距离,值越小,越柔和。
     */
    public void beginRubbler(final int bgColor, final int paintStrokeWidth,
        float touchTolerance) {
      TOUCH_TOLERANCE = touchTolerance;
      // 设置画笔
      mPaint = new Paint();
      // mPaint.setAlpha(0);
      // 画笔划过的痕迹就变成透明色了
      mPaint.setColor(Color.BLACK); // 此处不能为透明色
      mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
      // 或者
      // mPaint.setAlpha(0);
      // mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 

      mPaint.setAntiAlias(true);
      mPaint.setDither(true);
      mPaint.setStyle(Paint.Style.STROKE);
      mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圆角
      mPaint.setStrokeCap(Paint.Cap.ROUND); // 后圆角
      mPaint.setStrokeWidth(paintStrokeWidth); // 笔宽 

      // 痕迹
      mPath = new Path();
      ;
      // 覆盖
      // if (getLayoutParams().width == LayoutParams.FILL_PARENT) {
      //
      // }
      mBitmap = Bitmap.createBitmap(getLayoutParams().width,
          getLayoutParams().height, Config.ARGB_8888);
      mCanvas = new Canvas(mBitmap); 

      mCanvas.drawColor(bgColor);
      isDraw = true;
    } 

    @Override
    public boolean onTouchEvent(MotionEvent event) {
      if (!isDraw) {
        return true;
      }
      switch (event.getAction()) {
      case MotionEvent.ACTION_DOWN: // 触点按下
        // touchDown(event.getRawX(),event.getRawY());
        touchDown(event.getX(), event.getY());
        invalidate();
        break;
      case MotionEvent.ACTION_MOVE: // 触点移动
        touchMove(event.getX(), event.getY());
        invalidate();
        break;
      case MotionEvent.ACTION_UP: // 触点弹起
        touchUp(event.getX(), event.getY());
        invalidate();
        break;
      default:
        break;
      }
      return true;
    } 

    private void touchDown(float x, float y) {
      mPath.reset();
      mPath.moveTo(x, y);
      mX = x;
      mY = y;
    } 

    private void touchMove(float x, float y) {
      float dx = Math.abs(x - mX);
      float dy = Math.abs(y - mY);
      if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
        mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
        mX = x;
        mY = y;
      } 

    } 

    private void touchUp(float x, float y) {
      mPath.lineTo(x, y);
      mCanvas.drawPath(mPath, mPaint);
      mPath.reset();
    } 

  } 

接下来就是使用橡皮檫擦除了

  /**
   * FileName: RubblerAct.java
   * @Desc  该类通过调用Text_Rubbler这个类将在Activity上显示一片刮一刮的区域,可以出发触摸事件
   * @author HTP
   * @Date  20140312
   * @version 1.00
   */ 

  public class RubblerAct extends Activity {
    // 刮开后文字显示
    private TextView tv_rubbler;
    // 得到刮一刮的内容
    private Sentence mSentence;
    // 下一张
    private TextView tv_next; 

    @Override
    public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState); 

      // setContentView(new Rubble(this,"谢谢惠顾",new Rect(100, 200,
      // 300,250),2,1f,14)); 

      // /////////////////////////////////////////
      setContentView(R.layout.rubbler);
      // 设置的颜色必须要有透明度。
      ((Text_Rubbler) findViewById(R.id.rubbler)).beginRubbler(0xFFFFFFFF, 20,
          1f);// 设置橡皮擦的宽度等
      mSentence = new Sentence();
      // 随机初始化文字
      tv_rubbler = (TextView) findViewById(R.id.rubbler);
      String str = mSentence.getSentence();
      tv_rubbler.setText(str); 

      tv_next = (TextView) findViewById(R.id.tv_next); 

      // 点击下一步
      tv_next.setOnClickListener(new OnClickListener() { 

        @Override
        public void onClick(View v) {
          // TODO Auto-generated method stub
          String str = mSentence.getSentence();
          tv_rubbler.setText(str);
          ((Text_Rubbler) findViewById(R.id.rubbler))// 初始化状态
              .beginRubbler(0xFFFFFFFF, 20, 1f); 

        }
      }); 

    } 

    class Rubble extends View { 

      private final int PAINT_STROKE_WIDTH;
      private final float TOUCH_TOLERANCE; // 填充距离,使线条更自然,柔和,值越小,越柔和。
      private final int TEXT_SIZE; 

      private Bitmap mBitmap;
      // 画布
      private Canvas mCanvas;
      // 画笔
      private Paint mPaint;
      private Path mPath;
      private float mX, mY;
      private final int X, Y, W, H; 

      private final Rect touchRect; 

      public Rubble(Context context, String bgText, Rect rect,
          int paintStrokeWidth, float touchTolerance, int textSize) {
        super(context);
        setFocusable(true);
        touchRect = rect;
        W = rect.right - rect.left;
        H = rect.bottom - rect.top;
        X = rect.left;
        Y = rect.top;
        TEXT_SIZE = textSize;
        PAINT_STROKE_WIDTH = paintStrokeWidth;
        TOUCH_TOLERANCE = touchTolerance;
        setBackground(touchRect, bgText);
        initDrowTools(); 

      } 

      private void setBackground(Rect rect, String bgText) {
        DisplayMetrics dm = new DisplayMetrics();
        dm = this.getResources().getDisplayMetrics(); 

        Bitmap bitmap = Bitmap.createBitmap(dm.widthPixels,
            dm.heightPixels, Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap); 

        Paint paint = new Paint();
        paint.setColor(0x88000000);
        // paint.setStyle(Style.STROKE);
        // paint.setTextAlign(Align.CENTER);
        paint.setTextSize(TEXT_SIZE); 

        // paint.setTextScaleX(1.5f);
        canvas.drawColor(Color.WHITE);
        // 画字的坐标不好控制
        int x = rect.left
            + (rect.right - rect.left - bgText.length() * TEXT_SIZE)
            / 2;
        int y = rect.top + (rect.bottom - rect.top - TEXT_SIZE) / 2;
        // int y = 218+25;
        canvas.drawText(bgText, x, y, paint);
        Drawable drawable = new BitmapDrawable(bitmap);
        setBackgroundDrawable(drawable);
      } 

      private void initDrowTools() {
        // 设置画笔
        mPaint = new Paint();
        // mPaint.setAlpha(0);
        // 画笔划过的痕迹就变成透明色了
        mPaint.setColor(Color.BLACK); // 此处不能为透明色
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
        // 或者
        // mPaint.setAlpha(0);
        // mPaint.setXfermode(new
        // PorterDuffXfermode(PorterDuff.Mode.DST_IN)); 

        mPaint.setAntiAlias(true);
        mPaint.setDither(true);
        mPaint.setStyle(Paint.Style.STROKE);
        mPaint.setStrokeJoin(Paint.Join.ROUND); // 前圆角
        mPaint.setStrokeCap(Paint.Cap.ROUND); // 后圆角
        mPaint.setStrokeWidth(PAINT_STROKE_WIDTH); // 笔宽 

        // 痕迹
        mPath = new Path();
        ; 

        // 覆盖
        mBitmap = Bitmap.createBitmap(W, H, Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        mCanvas.drawColor(0x88000000); 

      } 

      @Override
      protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        mCanvas.drawPath(mPath, mPaint);
        // mCanvas.drawPoint(mX, mY, mPaint);
        canvas.drawBitmap(mBitmap, X, Y, null);
      } 

      @Override
      public boolean onTouchEvent(MotionEvent event) {
        System.out.print("X--" + event.getX());
        System.out.println("Y--" + event.getY());
        if (!touchRect.contains((int) event.getX(), (int) event.getY())) {
          return false;
        } 

        switch (event.getAction()) {
        // 触点按下
        case MotionEvent.ACTION_DOWN: {
          touchDown(event.getRawX(), event.getRawY());
          touchDown(event.getX() - touchRect.left, event.getY()
              - touchRect.top);
          invalidate();
          break;
        } 

        case MotionEvent.ACTION_MOVE: // 触点移动
          touchMove(event.getX() - touchRect.left, event.getY()
              - touchRect.top); 

          invalidate();
          break;
        case MotionEvent.ACTION_UP: // 触点弹起
          touchUp(event.getX() - touchRect.left, event.getY()
              - touchRect.top);
          invalidate();
          break;
        default:
          break;
        }
        return true;
      } 

      private void touchDown(float x, float y) {
        mPath.reset();
        mPath.moveTo(x, y);
        mX = x;
        mY = y;
      } 

      private void touchMove(float x, float y) {
        float dx = Math.abs(x - mX);
        float dy = Math.abs(y - mY);
        if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
          mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
          mX = x;
          mY = y;
        } 

      } 

      private void touchUp(float x, float y) {
        mPath.lineTo(x, y);
        mCanvas.drawPath(mPath, mPaint);
        mPath.reset();
      } 

    } 

    /**
     * 键盘事件,当按下back键的时候询问是否再按一次退出程序
     */
    // 退出时间
    private long exitTime = 0;
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
      if (keyCode == KeyEvent.KEYCODE_BACK
          && event.getAction() == KeyEvent.ACTION_DOWN) {
        if ((System.currentTimeMillis() - exitTime) > 2000) {
          Toast.makeText(getApplicationContext(), "再按一次退出程序",
              Toast.LENGTH_SHORT).show();
          exitTime = System.currentTimeMillis();
        } else {
          finish();
          System.exit(0); 

        }
        return true;
      }
      return super.onKeyDown(keyCode, event);
    } 

  }

实现效果如下:

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

(0)

相关推荐

  • 基于Android自定义控件实现刮刮乐效果

    只是简单的实现了效果,界面没怎么做优化,不过那都是次要的啦!!相信大家都迫不及待的想看效果图了吧, 其中主要的彩票视图类和橡皮擦类都是通过代码的方式构建视图,布局文件就一个主activity_main 上代码!! 主activity: package com.guaguale; import android.app.Activity; import android.os.Bundle; import android.view.Menu; import android.view.View; imp

  • angular.js实现购物车功能

    本文实例为大家分享了angular.js购物车功能的具体代码,供大家参考,具体内容如下 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>购物车</title> <script src="angularjs/angular.js"></script> <st

  • Android实现刮刮乐示例分析

    微信公众号有很多都做刮刮乐的活动,本文就实现了刮刮乐的效果,具体代码如下: 首先要做一个类似橡皮擦的东西吧,然后才能把纸上的笔迹擦除 /** * FileName: SplashActivity.java * * @desc 橡皮擦功能,类似刮刮乐效果 * @author HTP * @Date 20140311 * @version 1.00 */ public class Text_Rubbler extends TextView { private float TOUCH_TOLERANC

  • Android使用Canvas对象实现刮刮乐效果

    在淘宝.京东等电商举办活动的时候,经常可以看到在移动客户端推出的各种刮奖活动,而这种活动也受到了很多人的喜爱.从客户端的体验来说,这种效果应该是通过网页来实现的,那么,我们使用Android的自带控件能不能实现这种刮刮乐的效果呢?当然可以,本篇文章将介绍使用Canvas这个对象,如何实现"刮刮乐"的效果. 先看效果图 下面我们看一下如何使用代码实现 布局文件 <FrameLayout xmlns:android="http://schemas.android.com/a

  • Android刮刮乐效果-proterDuffXfermode的示例代码

    先看看实现的效果 这个场景主要是模拟我们有些app里面的刮刮乐中奖的效果,主要是利用Android的proterDuffXfermode这个类去实现的. proterDuffXfermode 在用Android中的Canvas进行绘图时,可以通过使用PorterDuffXfermode将所绘制的图形的像素与Canvas中对应位置的像素按照一定规则进行混合,形成新的像素值,从而更新Canvas中最终的像素颜色值,这样会创建很多有趣的效果.PorterDuffXfermode的功能十分的强大,其他的

  • Android studio实现刮刮乐的方法

    本文实例为大家分享了Android studio实现刮刮乐的具体代码,供大家参考,具体内容如下 MainActivity public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_mai

  • Android通过自定义view实现刮刮乐效果详解

    前言 已经有两个月没有更新博客了,其实这篇文章我早在两个月前就写好了,一直保存在草稿箱里没有发布出来.原因是有一些原理性的东西还没了解清楚,最近抽时间研究了一下混合模式,终于也理解了刮刮乐是怎么实现的,所以想继续分享一下自己的一些心得,先上效果图. 效果图: 实现原理 其实刮刮乐实现原理也不算很复杂,最关键的还是需要了解Paint的混合模式.因为刮刮乐是由两个bitmap组成的,一个是源图另一个是目标图,我们需要把目标图的颜色改成灰色,在源图上面盖上了一张灰色的目标图.当手指滑动屏幕时paint

  • 20行JS代码实现网页刮刮乐效果

    分享一段用canvas和JS制作刮刮乐的代码,JS部分去掉注释不到20行代码 效果如下 盖伦.jpg 刮刮乐.gif HTML部分 <body> ![](img/gailun.jpg) <canvas id="canvas" width="400" height="300"></canvas> </body> 没什么要特别注意的 为了效果加了些CSS样式 CSS部分 <style type=&

  • 移动端刮刮乐的实现方式(js+HTML5)

    程序员有一种惯性思维,就是看见一些会动的东西(带点科技含量的,猫啊,狗啊就算了),总要先想一遍,这玩意用代码是怎么控制的.比如电梯,路边的霓虹灯,遥控器,小孩子的玩具等,都统统被程序员"意淫"过. 有时候还会感觉程序员看世界会看的透彻一点............. 想必大家都玩过刮刮乐,下面就介绍一种刮刮乐的移动端实现方式!用到canvas 1.用HTML 5 canvas globalCompositeOperation 属性实现刮刮乐 思路: (1)首先需要一个盒子定位,确定刮刮乐

  • js和html5实现手机端刮刮卡抽奖效果完美兼容android/IOS

    绝对值得看的来篇,哈哈.本人亲自完成,有错误请大家指出: 现在的手机完美支持html5,所以如果手机端想要做个抽奖模块的话,用刮刮卡抽奖效果,相信这个互动体验是非常棒的 ​ps:由于本人没有wp8系统的手机,所以没法兼容wp8系统的,目前完美兼容android,IOS 如果要在pc浏览的话,得改下js,目前支持谷歌,火狐,ie>=10,如果网友想要的话我就去写个 代码如下: 复制代码 代码如下: <!DOCTYPE html> <html lang="en"&g

  • js HTML5手机刮刮乐代码

    手机刮刮乐HTML5代码, 使用原型prototype扩展了一个clearArc 清除圆内像素的功能, 此功能未完成扇形清除功能, 此外,在清除圆内的像素时,还有点瑕疵,右边和下边还不够圆滑,有明显的齿状.如果你找到修复方法请一定要告诉我哟.不过此清除方法用于刮刮乐已经完全满足需求了. <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <meta name="view

  • Android开发之自定义刮刮卡实现代码

    关于刮刮卡的实现效果不需要做太多解释,特别是在电商APP中,每当做活动的时候都会有它的身影存在,趁着美好周末,来实现下这个效果,也算是对零碎知识点的一个整合. 所涉及的知识点: 1.自定义View的一些流程 2.双缓冲绘图机制 3.Paint的绘图模式 4.触摸事件的一些流程 5.Bitmap的相关知识 实现思路: 其实非常简单,首先我们需要确定所要绘图的区域,然后对这块区域进行多层的绘图(背景层,前景层),然后去监听触摸事件,把手指触摸的区域的前景层给消除即可. 首先我们先来实现一个简单版的

随机推荐