首页 > 代码库 > 自定义View->刮刮乐

自定义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.Paint;import android.graphics.Path;import android.graphics.PorterDuff;import android.graphics.PorterDuffXfermode;import android.graphics.Rect;import android.graphics.Typeface;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;    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_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);        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        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;        default:            break;        }        invalidate();// 更新界面        return true;    }}

自定义属性:

 <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>

 

自定义View->刮刮乐