編輯:關於Android編程
很早之前就想研究一下Android中的塗鴉,其實也說不上是研究了,畢竟都是一些相對比較簡單的知識點。下面就對基於畫布(Canvas)和觸摸事件(onTouchEvent)來實現塗鴉和刮刮樂。
以下是兩個簡單的入門示例:塗鴉技術和刮刮樂的一些簡單分析和效果展示。
學習過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; }
分析:其實刮刮樂的實現思路跟塗鴉很像,都是在一塊地方瞎畫,並留下痕跡(說笑了,不過也不無道理。^_^)。不過有一點不同的就是我們在刮刮樂的繪制過程中畫筆經過的地方,是變成了透明的了。這裡你可能會說,那簡單了,不就是要我去覆蓋兩層圖片,在去繪制觸摸路徑,只是觸摸路徑的顏色是透明的。真的是這樣的麼?你可以試一試。當然,這樣是行不通的,關於實踐的最終效果大家可以自行嘗試。這裡的關鍵點在於我們要把上面的蒙層擦除且保留下面的底層。這裡就用到了圖形混合技術了。
圖形混合技術一聽名稱是不是就是感覺很高深,不過的確是很牛的技術,不過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); }
本文主要講述Android 6.0 SIM卡初始化流程,這個過程也涉及到UICC框架的初始化,UICC(Universal Integrated Circuit Card
我們今天所使用的方案只是android手機設備集成短信驗證碼功能的方案之一。我們所采用的方案是使用聚合數據的短信驗證sdk。 程序的界面如下所示: 實
一、smali語言簡介 1、宏觀的介紹:http://source.android.com/devices/tech/dalvik/instruction
Android手機字母A-Z排序側邊索引是非常常見的功能,在此提供快速集成框架.教你用Android studio工具一分鐘搞定這個效果.實現效果:以及點擊F跳轉效果&n