自定义View->刮刮乐

原理:canvas画上背景加文字<奖项>,再画上遮罩层,通过paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT)); 用户点击滑动后清除遮罩层。核心就是前面那句话。

package com.example.customshapedemo;


import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class GuaGuaKa extends View {
    Path path = new Path();// 用作划线
    Paint paint = new Paint();// 初始化画笔
    Bitmap mBitmap;// 最终要画在canvas上的bitmap
    Canvas mCanvas;// 用来给mBitmap上进行填充的画布

    String text = "";
    int text_size = 20;
    int background_color = Color.parseColor("#FFFAFA");
    int text_color = Color.BLACK;
    int mask_color = Color.parseColor("#CFCFCF");
    int strokeWidth = 20;
    Drawable mask_Drawable;

    public GuaGuaKa(Context context) {
        super(context);
        // TODO Auto-generated constructor stub
        initPaint();
    }

    public GuaGuaKa(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        // TODO Auto-generated constructor stub
        initParam(context, attrs);
        initPaint();
    }

    public GuaGuaKa(Context context, AttributeSet attrs) {
        super(context, attrs);
        // TODO Auto-generated constructor stub
        initParam(context, attrs);
        initPaint();
    }

    // 解析参数
    void initParam(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs,
                R.styleable.GuaGuaKa);
        background_color = typedArray.getColor(0, background_color);
        text = typedArray.getString(1);
        text_color = typedArray.getColor(2, text_color);
        text_size = typedArray.getInt(3, text_size);
        mask_Drawable = typedArray.getDrawable(4);
        if (mask_Drawable instanceof ColorDrawable) {
            mask_color = typedArray.getColor(4, mask_color);
        }
        strokeWidth = typedArray.getColor(5, strokeWidth);
        typedArray.recycle();
    }

    // 初始化画笔
    void initPaint() {
        paint.setAntiAlias(true);// 消除锯齿
        paint.setDither(true);// 消除色块
        paint.setStrokeJoin(Paint.Join.ROUND); // 线条对接处圆润
        paint.setStrokeCap(Paint.Cap.ROUND); // 线条圆润
        paint.setStrokeWidth(strokeWidth);
        paint.setStyle(Paint.Style.STROKE); // 空心
    }

    /**
     * 初始化刮刮卡的底层颜色,并且写上奖项
     * 
     * @param canvas
     */
    void initPrizeLayer(Canvas canvas, String str) {
        Paint p = new Paint();// 初始化画笔
        p.setStyle(Paint.Style.FILL);
        // 获取View的宽高
        int w = canvas.getWidth();
        int h = canvas.getHeight();
        // 最底层的背景色
        canvas.drawColor(background_color);
        // 初始化一个字体
        Typeface font = Typeface.create(Typeface.SANS_SERIF, Typeface.BOLD);
        p.setTypeface(font);
        p.setTextSize(text_size);
        p.setColor(text_color);
        // 获取字符串的宽高
        Rect r = new Rect();
        p.getTextBounds(str, 0, text.length(), r);
        int str_h = r.height();
        int str_w = r.width();
        // 给View的canvas中写上奖金
        canvas.drawText(str, (w - str_w) / 2, (h + str_h) / 2, p);
        // 创建一个bitmap然后画上遮罩层
        mBitmap = Bitmap.createBitmap(w, h, Config.ARGB_8888);
        mCanvas = new Canvas(mBitmap);
        if (!(mask_Drawable instanceof ColorDrawable)) {
            Bitmap bm = ((BitmapDrawable) mask_Drawable).getBitmap();
            int ww = bm.getWidth();
            int hh = bm.getHeight();
            float scale_w=(float)w/ww;
            float scale_h=(float)h/hh;
            Matrix matrix = new Matrix();   
            matrix.postScale(scale_w, scale_h);   
            Bitmap newbm = Bitmap.createBitmap(bm, 0, 0, ww, hh, matrix, true);   
            mCanvas.drawBitmap(newbm, 0, 0, null);
        } else {
            mCanvas.drawColor(mask_color);
        }
    }

    // 用户点击后划线操作
    void drawPath(Canvas canvas) {
        mCanvas.drawPath(path, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));
    }

    @Override
    protected void onDraw(Canvas canvas) {
        // TODO Auto-generated method stub
        //如果擦除超过70%则清空遮罩层
        if(isclear){
            initPrizeLayer(canvas, text);
            drawPath(canvas);
            return; 
        }
        initPrizeLayer(canvas, text);
        drawPath(canvas);
        canvas.drawBitmap(mBitmap, 0, 0, null);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // TODO Auto-generated method stub
        int x = (int) event.getX();
        int y = (int) event.getY();
        switch (event.getAction()) {
        case MotionEvent.ACTION_DOWN:
            path.moveTo(x, y);
            break;
        case MotionEvent.ACTION_MOVE:
            path.lineTo(x, y);
            break;
        case MotionEvent.ACTION_UP:
            new Thread(ClearPixelsCalc).start();
            break;
        default:
            break;
        }
        invalidate();// 更新界面
        return true;
    }

    boolean isclear=false;
    //计算擦掉的部分的线程
    Runnable ClearPixelsCalc=new Runnable() {
        
        @Override
        public void run() {
            // TODO Auto-generated method stub
            int count=0;
            int w=getWidth();
            int h=getHeight();
            int[] pixels=new int[w*h];
            mBitmap.getPixels(pixels, 0, w, 0, 0, w, h);
            for (int i = 0; i < w; i++) {
                for (int j = 0; j < h; j++) {
                    int idx=i+j*w;
                    if(pixels[idx]==0){
                        count++;
                    }
                }
            }
            if(count>0&&w*h>0){
                if(count/(w*h*1.0f)>0.8){
                    isclear=true;
                    postInvalidate();
                }
            }
        }
    };
}

 

自定义属性:

 <declare-styleable name="GuaGuaKa">
        <attr name="backgroundColor" format="reference|color" />
        <attr name="text" format="reference|string" />
        <attr name="textColor" format="reference|color" />
        <attr name="textSize" format="integer" />
        <attr name="maskColor" format="reference|color" />
        <attr name="strokeWidth" format="integer" />
  </declare-styleable>

View引入:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:customshape="http://schemas.android.com/apk/res/com.example.customshapedemo"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <com.example.customshapedemo.GuaGuaKa
        android:layout_width="300dp"
        android:layout_height="100dp"
        customshape:text="奖金 5,000,000 RMB"
        customshape:textSize="30"
        customshape:strokeWidth="50"
         />

</RelativeLayout>

 

posted @ 2014-11-21 18:16  q429786006  阅读(182)  评论(0编辑  收藏  举报