Android塗鴉技術及刮刮樂樣本分析,android刮刮樂

來源:互聯網
上載者:User

Android塗鴉技術及刮刮樂樣本分析,android刮刮樂
概述:

  很早之前就想研究一下Android中的塗鴉,其實也說不上是研究了,畢竟都是一些相對比較簡單的知識點。下面就對基於畫布(Canvas)和觸摸事件(onTouchEvent)來實現塗鴉和刮刮樂。


參考:

http://blog.csdn.net/lmj623565791/article/details/40162163

此人的部落格的確很好,想學習的同學也可以去參考一下這個大牛的其他部落格。

http://blog.csdn.net/t12x3456/article/details/10432935


樣本分析:

以下是兩個簡單的入門樣本:塗鴉技術和刮刮樂的一些簡單分析和效果展示。


1.塗鴉  思路分析及代碼展示

  學習過Canvas的同學應該都知道我們可以通過在一個View上覆蓋一個canvas,並實現View的onTouchEvent方法就可以在Canvas上留下觸控螢幕幕時的軌跡,對於軌跡的記錄還有一個類需要去瞭解——Path。關於Canvas更多的知識請點擊這裡查看。

  Android在繪製介面的時候會獲得布局中控制項的大小、位置等參數之後再去繪製。而這裡我們只是通過onMeasure和onDraw來繪製,沒有用到onLayout是因為這裡只有一個控制項,沒有太多動態布局需要處理。對於路徑的記錄則需要onTouchEvent實現。

  測量大小:

protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = getMeasuredWidth();        int height = getMeasuredHeight();                // 初始化bitmap        mBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);        mCanvas = new Canvas(mBitmap);    }

  繪製:

protected void onDraw(Canvas canvas) {        drawPath();        canvas.drawBitmap(mBitmap, 0, 0, null);    }

  路徑繪製:

  我們通過Path儲存我們觸摸的路徑軌跡。如下:

private void drawPath() {        mFingerPaint.setStyle(Paint.Style.STROKE);        mCanvas.drawPath(mPath, mFingerPaint);    }

  觸摸事件:

  對於觸摸事件有一個非常重要而且不可忽視的類就是MotionEvent。它有以下三個常用的動作事件:

  1.MotionEvent.ACTION_DOWN// 觸摸按下時

  2.MotionEvent.ACTION_MOVE// 觸摸在移動過程中

  3.MotionEvent.ACTION_UP  // 觸摸離開時


下面就看看onTouchEvent事件的實現過程:

public boolean onTouchEvent(MotionEvent event) {        int action = event.getAction();        int x = (int) event.getX();        int y = (int) event.getY();        switch (action) {        case MotionEvent.ACTION_DOWN:            actionMotionEventDown(x, y);            break;                    case MotionEvent.ACTION_MOVE:            actionMotionEventMove(x, y);            break;        }        invalidate();        return true;    }

上面的代碼中,我們在按下的時候實現了按下的邏輯,在手指在螢幕上移動的時候實現了Move的邏輯。還有別忘了invalidate()。invalidate()函數的主要作用是請求View樹進行重繪,如果你不去調用它,結果就是什麼事情都不會發生。


 



2.刮刮樂  思路分析及代碼展示

  分析:其實刮刮樂的實現思路跟塗鴉很像,都是在一塊地方瞎畫,並留下痕迹(說笑了,不過也不無道理。^_^)。不過有一點不同的就是我們在刮刮樂的繪製過程中畫筆經過的地方,是變成了透明的了。這裡你可能會說,那簡單了,不就是要我去覆蓋兩層圖片,在去繪製觸摸路徑,只是觸摸路徑的顏色是透明的。真的是這樣的嗎?你可以試一試。當然,這樣是行不通的,關於實踐的最終效果大家可以自行嘗試。這裡的關鍵點在於我們要把上面的蒙層擦除且保留下面的底層。這裡就用到了圖形混合技術了。

  圖形混合技術一聽名稱是不是就是感覺很高深,不過的確是很牛的技術,不過Java已經給我們封裝好了,我們只要知道怎麼使用即可,而使用它則就不那麼艱難了。

  關於圖形混合的詳細描述,大家可以參考這裡,我就不重複製造輪子了。不過我還是要簡單介紹一下Xfermode三個子類下的一個:PorterDuffXfermode。這是一個非常強大的轉換模式,使用它,可以使用映像合成的16條Porter-Duff規則的任意一條來控制Paint如何與已有的Canvas映像進行互動。


Porter-Duff規則如下:


PorterDuff.Mode為枚舉類,一共有16個枚舉值:
1.PorterDuff.Mode.CLEAR
  所繪製不會提交到畫布上。
2.PorterDuff.Mode.SRC
   顯示上層繪製圖片
3.PorterDuff.Mode.DST
  顯示下層繪製圖片
4.PorterDuff.Mode.SRC_OVER
  正常繪製顯示,上下層繪製疊蓋。
5.PorterDuff.Mode.DST_OVER
  上下層都顯示。下層居上顯示。
6.PorterDuff.Mode.SRC_IN
   取兩層繪製交集。顯示上層。
7.PorterDuff.Mode.DST_IN
  取兩層繪製交集。顯示下層。
8.PorterDuff.Mode.SRC_OUT
 取上層繪製非交集部分。
9.PorterDuff.Mode.DST_OUT
 取下層繪製非交集部分。
10.PorterDuff.Mode.SRC_ATOP
 取下層非交集部分與上層交集部分
11.PorterDuff.Mode.DST_ATOP
 取上層非交集部分與下層交集部分
12.PorterDuff.Mode.XOR
  異或:去除兩圖層交集部分
13.PorterDuff.Mode.DARKEN
  取兩圖層全部地區,交集部分顏色加深
14.PorterDuff.Mode.LIGHTEN
  取兩圖層全部,點亮交集部分顏色
15.PorterDuff.Mode.MULTIPLY
  取兩圖層交集部分疊加後顏色
16.PorterDuff.Mode.SCREEN
  取兩圖層全部地區,交集部分變為透明色


我們需要的正是:DstOut這一條。代碼中我們是這樣實現的:

private void drawPath() {        mFingerPaint.setStyle(Paint.Style.STROKE);        // 設定兩張圖片相交時的模式(取下層繪製非交集部分)        mFingerPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_OUT));        mCanvas.drawPath(mPath, mFingerPaint);    }

測量和繪製過程如下:

@Override    protected void onDraw(Canvas canvas) {        canvas.drawText(mText, getWidth() / 2 - mTextBound.width() / 2, getHeight() / 2 + mTextBound.height() / 2, mBackPint);                if (!isComplete) {            drawPath();            canvas.drawBitmap(mBitmap, 0, 0, null);        }    }    @Override    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {        super.onMeasure(widthMeasureSpec, heightMeasureSpec);        int width = getMeasuredWidth();        int height = getMeasuredHeight();                // 初始化bitmap        mBitmap = Bitmap.createBitmap(width, height, Config.ARGB_8888);        mCanvas = new Canvas(mBitmap);        // 繪製遮蓋層        mFingerPaint.setStyle(Paint.Style.FILL);        mCanvas.drawRoundRect(new RectF(0, 0, width, height), 30, 30, mFingerPaint);        mCanvas.drawBitmap(BitmapFactory.decodeResource(getResources(), R.drawable.mask), null, new RectF(0, 0, width, height), null);    }

此外還有一篇也是使用了此技術的部落格,點擊這裡進行查看。


 



源碼下載:

http://download.csdn.net/detail/u013761665/8737527

聯繫我們

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

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

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.