Android項目刮刮獎詳解(四)

來源:互聯網
上載者:User

Android項目刮刮獎詳解(三)

前言

上一期我們已經是完成了刮刮卡的準系統,本期就是給我們的項目增加個功能以及美化一番

目標
  • 增加功能 使用者刮卡刮到一定程度的時候,清除遮蓋層
  • 在遮蓋層放張圖片,增加使用者體驗
  • 增加一個刮完獎回調監聽

    實現1.自動消除效果

    我們首先來瞭解一下bitmap的getPixels方法

      getPixels(@ColorInt int[] pixels, int offset, int stride,int x, int y, int width, int height) 

    getPixels()函數把一張圖片,從指定的位移位置(offset),指定的位置(x,y)截取指定的寬高(width,height ),把所得映像的每個像素顏色轉為int值,存入pixels。
    至於參數stride,查了資料,發現看不太懂,於是便是沒有繼續深究,我們直接用就是了

我們需要一個線程來完成我們的計算像素,因為計算不能一直在UI線程裡面執行,可能會出現卡頓,當使用者抬起手指的時候,我們就啟動這個計算進程來計算使用者所擦除的像素點

本功能有些複雜,要想看得懂,需要瞭解 UI線程更新View的知識和java中進程部分知識,推薦看一下這篇子進程更新UI

    private Runnable mRunnable = new Runnable() {    int[] pixels;    @Override    public void run() {        int w = mBitmap.getWidth();        int h = mBitmap.getHeight();        float wipeArea = 0;//擦除像素點計數,初始為0        float totalArea = w * h;//全部的像素點        pixels = new int[w * h];        /**         * pixels   接收位元影像顏色值的數組         * offset   寫入到pixels[]中的第一個像素索引值         * stride   pixels[]中的行間距個數值(必須大於等於位元影像寬度)。可以為負數         * x      從位元影像中讀取的第一個像素的x座標值。         * y      從位元影像中讀取的第一個像素的y座標值         * width    從每一行中讀取的像素寬度         * height    讀取的行數         */        Bitmap b = mBitmap;        b.getPixels(pixels, 0, w, 0, 0, w, h);       //for迴圈尋找使用者擦除的像素點,為0則是擦除,wipeArea+1        for (int i = 0; i < totalArea; i++) {            if (pixels[i] == 0) {                wipeArea++;            }        }        //        if (wipeArea > 0 && totalArea > 0) {            int percent = (int) (wipeArea * 100 / totalArea);//計算比例            if (percent > 50) {                isClear = true;//isClear是之前聲明的全域變數,                postInvalidate();//子進程中調用此方法重繪View            }        }    }};

上述代碼中有個for迴圈用來記錄擦除像素點,有些疑問,因為鴻洋大神用的不一樣,鴻洋大神使用的是下面的嵌套迴圈

    for (int i = 0; i < w; i++) {            for (int j = 0; j < h; j++) {                int index = i + j * w;                if (pixels[index] == 0) {                    wipeArea++;                }            }        }

之後我們還需要改寫代碼,首先,是在觸摸事件中增加我們對使用者抬起手指的操作

     case MotionEvent.ACTION_UP:            new Thread(mRunnable).start();            break;

之後,通過isClear這個變數來控制是否畫出路徑,onDraw方法之中進行這樣的修改

    protected void onDraw(Canvas canvas) {        canvas.drawText(message,mBitmap.getWidth()/2-mBackground.width()/2,getMeasuredHeight()/2+mBackground.height()/2,messagePaint);        if (!isClear){            drawPath();            canvas.drawBitmap(mBitmap, 0,0, null);        }    }

當canvas寫出了文字,之後就不畫遮蓋層了,這樣便是達到了清除遮蓋層的效果

這裡需要注意一下if中的條件,還要,isClear還得用volatile修飾,通俗的講就是加了個鎖,防止並發出現錯誤

2.遮蓋層繪製圖片

可能大家對這個功能很不屑,認為自己之前不是會了嗎,其實沒有那麼簡單,我自己嘗試的時候都出現了錯誤,經過搜尋資料嘗試才達到效果。
先說下我遇到的問題

  • 圖片只顯示一部分
  • 畫筆清除不了圖片,畫的時候出現黑色的筆跡

第一個問題,我們可以通過Bitmap的靜態方法來解決

    public static Bitmap createScaledBitmap(Bitmap src, int dstWidth, int dstHeight,boolean filter)

傳入一個需要調整大小的bitmap對象,之後,長度和高度,最後一個參數傳入true
background = Bitmap.createScaledBitmap(background,width,height,true);//對bitmap進行縮放

第二個問題,因為我們使用的是雙緩衝技術繪圖,所以,我們需要將遮蓋層的圖片先繪製在mBitmap中去
mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);//以獲得的寬高建立一個32位的bitmap
mCanvas = new Canvas(mBitmap);
mCanvas.drawBitamap(background,0,0,null);

3.回調介面
    public interface onGuaCompleteListener{        void complete();    }    private onGuaCompleteListener mlistener;    public void setGuaCompleteListener(onGuaCompleteListener mlistener) {        this.mlistener = mlistener;    }

之後在onDraw方法裡添加回調

    protected void onDraw(Canvas canvas) {        Log.d(TAG, "onDraw: 畫");        canvas.drawText(message,mBitmap.getWidth()/2-mBackground.width()/2,getMeasuredHeight()/2+mBackground.height()/2,messagePaint);        if (!isClear){            drawPath();            canvas.drawBitmap(mBitmap, 0,0, null);        }else if (mlistener!=null){            mlistener.complete();        }    }

當畫到百分之60的時候,就會將isClear的值變為true,同時,就會進入到else if中,回調完成刮獎的介面

我們到MainActivity中設定監聽器來監聽刮刮卡的完成操作,彈出一個Toast或者是對話方塊,我這裡簡單起見就直接彈出一個Toast

    GuajiangView mView = (GuajiangView) findViewById(R.id.view);    mView.setGuaCompleteListener(new GuajiangView.onGuaCompleteListener() {        @Override        public void complete() {            Toast.makeText(MainActivity.this, "hello", Toast.LENGTH_SHORT).show();        }    });    
測試圖

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

Tags Index: