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();// 初始化bitmapmBitmap = 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);}
測量和繪制過程如下:
@Overrideprotected 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);}}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = getMeasuredWidth();int height = getMeasuredHeight();// 初始化bitmapmBitmap = 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
總結
以上是生活随笔為你收集整理的Android涂鸦技术及刮刮乐示例分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android控件ActionBar浅析
- 下一篇: Java设计模式——单件模式