Android實現刮刮樂效果

jopen 10年前發布 | 44K 次閱讀 Android 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();  
    }  

}  </pre><a class="CopyToClipboard" title="copy" href="/misc/goto?guid=4959614077324934931"></a></div>

</div> </div>
接下來就是使用橡皮檫擦除了

    /**

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

}  </pre><a style="text-indent:0px;" title="派生到我的代碼片" href="/misc/goto?guid=4959614077408945553" target="_blank"></a></div>

</div> </div>

實現效果如下:

Android實現刮刮樂效果

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

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!