最近實現了android裡的一個機能,在activity裡面畫了一個類比的時針,然後觸摸上面的時針跟分針可以實現調時間的功能。
其實,說起原來來還是挺簡單的,但是我花了將近一周的時間才全部實現,有點慚愧。。。
一、在activity裡面畫一個時鐘,有時針跟分針,代碼略。
錶盤、時針和分針都是imageView,建立一個位元影像,然後上面蓋了分針的imageView,位元影像旋轉一定的角度,這個時候顯示的就是時針的角度。
二、給分針添加onTouch事件:
由於imageView是一層蓋著一層的,所以My Code裡是分針的imageView在最上面,所以我的觸摸事件就全部寫在分針上;
基本原理:當我的手指觸摸到mImageView_minuteHand的時候,會有個點座標,根據點的座標來判斷我點的位置,是類比的時鐘介面:
我把時鐘分為四個象限,0-15分鐘為第一象限,15-30分鐘為第二象限,30-45分鐘為第三象限,45-60分鐘為第四象限,分這四塊主要是為了下面的計算角度準備的。
0分的時候為0度,以o點為中心,這樣一來我手在圓盤裡點到某個位置的時候,串連圓心就有一條直線,圓心與0分串連也有一條直線,就可以計算兩條直線的夾角了,但是由於圓心與0分串連的直線斜率不存在,所以我用圓心與15分的連線代替,圖中紅線所示。
計算兩條直線的夾角代碼:
[java]
double k1 = (double)(startY - centerY)/(startX - centerX);
double k2 = (double)(endY - centerY)/(endX - centerX);
double tmpDegree = Math.atan((Math.abs(k1 - k2))/(1 + k1*k2)) / Math.PI * 180 ;
double k1 = (double)(startY - centerY)/(startX - centerX);
double k2 = (double)(endY - centerY)/(endX - centerX);
double tmpDegree = Math.atan((Math.abs(k1 - k2))/(1 + k1*k2)) / Math.PI * 180 ;startX與startY為圖中的15分所在點,centerX與centerY為圖中的中心點o點,endX與endY就是我手指所點的點,接下來就是計算我手指所在的點與圓心的連線和0度的夾角:
[java]
if(endY < width/2 && endX > width/2){ //位於第一象限
firstTouchDegree = 90 - tmpDegree;
System.out.println("firstTouchDegree<90..."+ firstTouchDegree);
}else if (endY > width/2 && endX > width/2 ) { //位於第二象限
firstTouchDegree = 90 + tmpDegree;
System.out.println("firstTouchDegree90-180..."+ firstTouchDegree);
}else if (endY > width/2 && endX < width/2 ) { //位於第三象限
firstTouchDegree = 270 - tmpDegree;
System.out.println("firstTouchDegree180-270..."+ firstTouchDegree);
}else if (endX < width/2 && endY < width/2) { //位於第四象限
firstTouchDegree = 180 + 90 + tmpDegree;
System.out.println("firstTouchDegree>270..."+ firstTouchDegree);
}else if (endX == width/2 && endY < width/2) { //位於0分位置
firstTouchDegree = 0.0;
}else if (endX == width/2 && endY > width/2) { //位於30分位置
firstTouchDegree = 180.0;
}
if(endY < width/2 && endX > width/2){ //位於第一象限
firstTouchDegree = 90 - tmpDegree;
System.out.println("firstTouchDegree<90..."+ firstTouchDegree);
}else if (endY > width/2 && endX > width/2 ) { //位於第二象限
firstTouchDegree = 90 + tmpDegree;
System.out.println("firstTouchDegree90-180..."+ firstTouchDegree);
}else if (endY > width/2 && endX < width/2 ) { //位於第三象限
firstTouchDegree = 270 - tmpDegree;
System.out.println("firstTouchDegree180-270..."+ firstTouchDegree);
}else if (endX < width/2 && endY < width/2) { //位於第四象限
firstTouchDegree = 180 + 90 + tmpDegree;
System.out.println("firstTouchDegree>270..."+ firstTouchDegree);
}else if (endX == width/2 && endY < width/2) { //位於0分位置
firstTouchDegree = 0.0;
}else if (endX == width/2 && endY > width/2) { //位於30分位置
firstTouchDegree = 180.0;
}上述代碼中的firstTouchDegree是我手指當前點下去的位置與0度的夾角,上面也提到了,我的imageView都是一層層的疊在一起的,所以我只能觸摸到最上層的imageView,本例中是mImageView_minuteHand,所以接下來我就是要判斷我點的位置是時針還是分針,但是如果時針跟分針重合在一塊的話,那麼我點這個位置的時候動的肯定就是分針而不是時針。。。
時針和分針的角度一開始是可以確定的,一個圓是360度,所以我一分鐘就是6°,一個小時是30°;如果分鐘數不為0,那麼時針的角度就是hour * 30 + minute * 0.5;
得到了時針和分針的角度以後,就可以判斷如果我點的是時針附近,那麼我轉動我手指位置的時候就讓時針旋轉,如果位置在分針附近,那麼旋轉的時候就是分針在旋轉。
在圖層的最底層是一層scrollView,所以當我檢測到onTouchListener的時候,我要讓我的父view停止轉動:
[java]
v.getParent().requestDisallowInterceptTouchEvent(true);
v.getParent().requestDisallowInterceptTouchEvent(true);然後就是根據我手指轉動的位置來旋轉我的圖片即可。
PS:本人把時針跟分針的觸摸事件都寫在一起去了,只是單純的根據我手指的位置來判斷轉動哪個指標,而不是給每個指標寫定了某個事件,總覺得有些不妥。。。。