技术联盟

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);  
        }  
      
    }

 

实现效果如下:

Android实现刮刮乐效果

来自:http://blog.csdn.net/qq544529563/article/details/38795401

Share this:

码字很辛苦,转载请注明来自技术联盟《Android实现刮刮乐效果》

评论