該系列教程概述與目錄:http://www.cnblogs.com/chengyujia/p/5787111.html 一、知識點講解 當我們點擊系統自帶的按鈕時,按鈕的外觀會發生變化。上篇博文中我們畫了一個三角形按鈕,但點擊還不能變色,下麵我們就來實現點擊變色功能。從知識體繫上我們需要瞭解以下兩個 ...
該系列教程概述與目錄:http://www.cnblogs.com/chengyujia/p/5787111.html
一、知識點講解
當我們點擊系統自帶的按鈕時,按鈕的外觀會發生變化。上篇博文中我們畫了一個三角形按鈕,但點擊還不能變色,下麵我們就來實現點擊變色功能。
從知識體繫上我們需要瞭解以下兩個知識點
- 1.如何知道手指點擊了我們的控制項?
辦法是重寫View中的onTouchEvent方法。當手指觸摸到我們的控制項時,系統會通過該方法告訴我們。該方法還有一個類型為MotionEvent的參數,通過該參數我們就能知道當前觸摸事件的具體類型,比如按下、移動、抬起等。
我們可以讓按鈕在正常情況下顯示一個較暗的顏色,按下時顯示一個較亮的顏色,抬起後再恢復到較暗的顏色。這樣就實現了點擊變色的效果了。
- 2.如何變色?
View中提供了一個叫invalidate的方法,每次調用該方法,系統都會重新調用onDraw方法來重繪本控制項。我們要做的就是在onDraw中判斷當前的觸摸動作,如果是按下就畫一個高亮的三角形,沒有觸摸或按下抬起後就畫一個較暗的三角形。
瞭解了相關的知識點,下麵我們就通過代碼來實現。
二、代碼實現
以下是當前DirectionKeys類的全部代碼:
package net.chengyujia.happysnake; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.util.AttributeSet; import android.view.MotionEvent; import android.view.View; /** * Created by ChengYuJia on 2016/8/19. * 屏幕上的虛擬方向鍵 */ public class DirectionKeys extends View { //左三角形按壓時的顏色(較亮) private int leftPressedColor = 0xFFFF0000; //左三角形正常顯示的顏色(較暗) private int leftNormalColor = 0xFFAA0000; //手觸摸屏幕的動作,初始值用一個MotionEvent中沒有用到的action值,比如-10,表示還沒有任何觸屏動作發生。 private int action = -10; //畫布的寬 private int width; //畫布的高 private int height; //畫左三角形的路徑 private Path pathLeft = new Path(); //畫筆 private Paint paint = new Paint(); //初始化方法是否執行過,確保初始化方法只執行一次。 private boolean initDone = false; //只有一個參數的構造方法是我們在程式中通過“new”關鍵字創建實例時調用。 public DirectionKeys(Context context) { super(context); } //有兩個參數的構造方法是系統在XML佈局文件中創建實例時調用。 public DirectionKeys(Context context, AttributeSet attrs) { super(context, attrs); } //初始化方法 private void init(Canvas canvas) { /*獲取畫布的長和寬*/ width = canvas.getWidth(); height = canvas.getHeight(); /* (小提示:在電腦中一般都是將左上角作為坐標原點的) 畫布上四個頂點和中心點的坐標如下: 左上點 0,0 左下點 0,height 右上點 width,0 右下點 width,height 中心點 width/2,height/2 */ /*設置左三角形的路徑數據*/ //從畫布左上點開始 pathLeft.moveTo(0, 0); //畫直線到畫布中心點 pathLeft.lineTo(width / 2, height / 2); //再畫直線到畫布左下點 pathLeft.lineTo(0, height); //自動閉合圖形。從最後一個點(左下點)畫直線到第一個點(左上點)。 pathLeft.close(); } /** * 通過重寫父類的onDraw方法來繪製我們需要的圖形 * 該方法會在控制項第一次顯示時被系統調用,併在之後每次調用invalidate方法後被系統調用。 * * @param canvas 這裡的canvas是系統提供的一塊矩形畫布,我們要做的就是在這塊畫布上畫我們想要的東西。 */ @Override protected void onDraw(Canvas canvas) { if (!initDone) { init(canvas); //確保初始化方法只執行一次 initDone = true; } if (action == MotionEvent.ACTION_DOWN) { //手按壓時高亮顯示 paint.setColor(leftPressedColor); } else { //沒有按或按下抬起後顯示較暗的顏色 paint.setColor(leftNormalColor); } //畫左三角形 canvas.drawPath(pathLeft, paint); } /** * 如果手觸摸到我們的控制項,系統會通過該方法告訴我們 * * @param event 系統給我們傳遞的觸摸事件參數 * @return 如果該觸摸事件被我們處理了返回true,反之返回false。 */ @Override public boolean onTouchEvent(MotionEvent event) { action = event.getAction(); //ACTION_DOWN表示手按到屏幕,ACTION_UP表示手從屏幕上抬起。我們只處理這兩種動作。 if (action == MotionEvent.ACTION_DOWN || action == MotionEvent.ACTION_UP) { //invalidate方法是告訴系統當前控制項需要重繪,系統會再次調用onDraw方法來實現重繪。 invalidate(); return true; } return false; } }
上面註釋比較詳細,主要就3個方法onDraw(繪圖)、onTouchEvent(監聽觸摸事件)、invalidate(讓系統調用onDraw方法實現重繪)。
另外Path對象和Paint對象只要初始化一次就可以了,沒必要每次onDraw的時候重新創建,提高程式性能。
三、運行效果
正常時顯示暗色:
按下時顯示亮色:
測試的時候會發現,點擊非三角形區域也會變色,這因為我們還沒有對點擊的位置做判斷,這個會在後面講解。
先到這裡,下文繼續。:)