日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

Android涂鸦技术及刮刮乐示例分析

發(fā)布時間:2025/3/20 Android 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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是因為這里只有一個控件,沒有太多動態(tài)布局需要處理。對于路徑的記錄則需要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樹進行重繪,如果你不去調用它,結果就是什么事情都不會發(fā)生。


? 效果圖



2.刮刮樂

? 思路分析及代碼展示

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

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

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


Porter-Duff規(guī)則如下:


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
? 取兩圖層全部區(qū)域,交集部分顏色加深
14.PorterDuff.Mode.LIGHTEN
? 取兩圖層全部,點亮交集部分顏色
15.PorterDuff.Mode.MULTIPLY
? 取兩圖層交集部分疊加后顏色
16.PorterDuff.Mode.SCREEN
? 取兩圖層全部區(qū)域,交集部分變?yōu)橥该魃?br />


我們需要的正是: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涂鸦技术及刮刮乐示例分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。