在和手機(jī)屏幕進(jìn)行交互的過程中,我們存在多種多樣的手勢(shì),想比如單擊,雙擊,滑動(dòng),兩指的縮放,那么Android是怎么對(duì)我們的手勢(shì)進(jìn)行監(jiān)聽的呢?通過本篇文章的學(xué)習(xí),你講對(duì)Android手勢(shì)處理有個(gè)大致的了解:
1.Android系統(tǒng)提供的手勢(shì)監(jiān)聽器OnGestureListener
2.Android系統(tǒng)提供的手勢(shì)監(jiān)聽器SimpleOnGestureListener
3.onTouchEvent自己去識(shí)別各種手勢(shì)
一.手勢(shì)監(jiān)聽器OnGestureListener
1.activity實(shí)現(xiàn)這個(gè)接口需要重寫一下方法:
@Override
public boolean onDown(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)--->onDown");
return false;
}
@Override
public void onShowPress(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)--->onShowPress");
}
@Override
public boolean onSingleTapUp(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)--->onSingleTapUp");
return false;
}
@Override
public boolean onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Log.i("lvv","手勢(shì)--->onScroll");
return false;
}
@Override
public void onLongPress(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)--->onLongPress");
}
@Override
public boolean onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1) {
Log.i("lvv","手勢(shì)--->onFling");
return true;
}
這些函數(shù)在什么時(shí)候會(huì)觸發(fā):
onDown(MotionEvent motionEvent):用戶按下屏幕就會(huì)觸發(fā)
onShowPress(MotionEvent motionEvent):如果是按下的時(shí)間超過瞬間,而且在按下的時(shí)候沒有松開或者是拖動(dòng)的,那么onShowPress就會(huì)執(zhí)行,這個(gè)瞬間無法定義
onLongPress(MotionEvent e):長(zhǎng)按觸摸屏,超過一定時(shí)長(zhǎng),就會(huì)觸發(fā)這個(gè)事件
onSingleTapUp(MotionEvent motionEvent):從名子也可以看出,一次單獨(dú)的輕擊抬起操作,也就是輕擊一下屏幕,立刻抬起來,才會(huì)有這個(gè)觸發(fā),當(dāng)然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以也就不會(huì)觸發(fā)這個(gè)事件
onFling(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1):滑屏,用戶按下觸摸屏、快速移動(dòng)后松開,由1個(gè)MotionEvent ACTION_DOWN, 多個(gè)ACTION_MOVE, 1個(gè)ACTION_UP觸發(fā)
onScroll(MotionEvent motionEvent, MotionEvent motionEvent1, float v, float v1):在屏幕上拖動(dòng)事件
最后兩個(gè)方法有點(diǎn)類似,四個(gè)參數(shù)的意義也一樣:
motionEvent:第1個(gè)ACTION_DOWN MotionEvent
motionEvent1:最后一個(gè)ACTION_MOVE MotionEvent
v:X軸上的移動(dòng)速度,像素/秒
v1:Y軸上的移動(dòng)速度,像素/秒
2.創(chuàng)建手勢(shì)類,并重寫onTouchEvent方法,把onTouchEvent托管給手勢(shì)類
//創(chuàng)建手勢(shì)類并添加OnGestureListener監(jiān)聽器
GestureDetector gd=new GestureDetector(this,this);
//activity重寫方法
@Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);//把onTouchEvent托管給手勢(shì)類
}
滑動(dòng)的時(shí)候會(huì)調(diào)用: onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling
單擊:onDown---》onSingleTapUp
雙擊:onDown---》onSingleTapUp---》onDown---》onSingleTapUp
二.手勢(shì)監(jiān)聽器SimpleOnGestureListener
SimpleOnGestureListener手勢(shì)監(jiān)聽器相比于OnGestureListener監(jiān)聽器的優(yōu)點(diǎn)在于不需要重寫所有方法,只需要關(guān)注自己想要點(diǎn)方法即可,而且它還包含了下面OnDoubleTapListener監(jiān)聽器單雙擊的方法,因此一般情況下用這個(gè)監(jiān)聽器最好:
//創(chuàng)建手勢(shì)類添加監(jiān)聽器
GestureDetector gd=new GestureDetector(this,listener);
GestureDetector.SimpleOnGestureListener listener=new GestureDetector.SimpleOnGestureListener(){
@Override
public boolean onSingleTapConfirmed(MotionEvent e) {
return super.onSingleTapConfirmed(e);//單擊
}
@Override
public boolean onDoubleTap(MotionEvent e) {
return super.onDoubleTap(e);//雙擊
}
@Override
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
return super.onFling(e1, e2, velocityX, velocityY);
}
};
同時(shí),有一個(gè)OnDoubleTapListener是只需要關(guān)注單擊和雙擊事件的:
//創(chuàng)建手勢(shì)類添加監(jiān)聽器
GestureDetector gd=new GestureDetector(this,this);
gd.setOnDoubleTapListener(listener2);//手勢(shì)類添加OnDoubleTapListener監(jiān)聽器
//activity重寫方法
@Override
public boolean onTouchEvent(MotionEvent event) {
return gd.onTouchEvent(event);//把onTouchEvent托管給手勢(shì)類
}
GestureDetector.OnDoubleTapListener listener2=new GestureDetector.OnDoubleTapListener() {
@Override
public boolean onSingleTapConfirmed(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)---》onSingleTapConfirmed");//單擊事件
return false;
}
@Override
public boolean onDoubleTap(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)---》onDoubleTap");//雙擊事件
return true;
}
@Override
public boolean onDoubleTapEvent(MotionEvent motionEvent) {
Log.i("lvv","手勢(shì)---》onDoubleTapEvent");
return false;
}
};
三.onTouchEvent自己識(shí)別
可以通過重寫onTouchEvent方法獲取event.getAction()得到手指的狀態(tài),按下,移動(dòng),抬起,判斷是一根手指的時(shí)候就是拖動(dòng)狀態(tài),可以用于模仿微信拖動(dòng)圖片拖動(dòng)到下方然后消失,判斷是兩根手指的時(shí)候就是縮放狀態(tài),用于模仿微信雙手縮放圖片根據(jù)判斷兩根手指的距離是增加還是減少進(jìn)行放大和縮小。
private int currentStatus=STATUS_INIT;//當(dāng)前的狀態(tài)
public static final int STATUS_INIT = 1;//初始化的狀態(tài)
public static final int STATUS_ZOOM_OUT = 2;//圖片放大狀態(tài)常量
public static final int STATUS_ZOOM_IN = 3;//圖片縮小狀態(tài)常量
public static final int STATUS_MOVE = 4;//圖片拖動(dòng)狀態(tài)常量
private float xMove = -1;//記錄當(dāng)前手指的橫坐標(biāo)
private float lastXMove = -1;//記錄上次手指移動(dòng)時(shí)的橫坐標(biāo)
private float yMove = -1;//記錄當(dāng)前手指的縱坐標(biāo)
private float lastYMove = -1;//記錄上次手指移動(dòng)時(shí)的縱坐標(biāo)
private double lastFingerDis;//記錄上次兩指之間的距離
private double fingerDis;//記錄當(dāng)前兩指之間的距離
private float scaledRatio;//記錄手指移動(dòng)的距離所造成的縮放比例
@Override
public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_POINTER_DOWN:
if (event.getPointerCount() == 2) {
// 當(dāng)有兩個(gè)手指按在屏幕上時(shí),計(jì)算兩指之間的距離
lastFingerDis = distanceBetweenFingers(event);
}
break;
case MotionEvent.ACTION_MOVE:
if (event.getPointerCount() == 1) {
// 只有單指按在屏幕上移動(dòng)時(shí),為拖動(dòng)狀態(tài)
xMove = event.getX();
yMove = event.getY();
if (lastXMove == -1 && lastYMove == -1) {
lastXMove = xMove;
lastYMove = yMove;
}
currentStatus = STATUS_MOVE;
// ------------拖動(dòng)數(shù)值----------------
//after(xMove,yMove),befor(lastXMove,lastYMove)
lastXMove = xMove;
lastYMove = yMove;
} else if (event.getPointerCount() == 2) {
// 有兩個(gè)手指按在屏幕上移動(dòng)時(shí),為縮放狀態(tài)
fingerDis = distanceBetweenFingers(event);
if (fingerDis > lastFingerDis) {
currentStatus = STATUS_ZOOM_OUT;
} else {
currentStatus = STATUS_ZOOM_IN;
}
// ------------縮放倍數(shù)----------------
scaledRatio = (float) (fingerDis / lastFingerDis);
}
break;
case MotionEvent.ACTION_POINTER_UP:
if (event.getPointerCount() == 2) {
// 手指離開屏幕時(shí)將臨時(shí)值還原
lastXMove = -1;
lastYMove = -1;
}
break;
case MotionEvent.ACTION_UP:
// 手指離開屏幕時(shí)將臨時(shí)值還原
lastXMove = -1;
lastYMove = -1;
break;
default:
break;
}
return true;
}
/**
* 計(jì)算兩個(gè)手指之間的距離。
*
* @param event
* @return 兩個(gè)手指之間的距離
*/
private double distanceBetweenFingers(MotionEvent event) {
float disX = Math.abs(event.getX(0) - event.getX(1));
float disY = Math.abs(event.getY(0) - event.getY(1));
return Math.sqrt(disX * disX + disY * disY);
}
四.總結(jié)
以上就是關(guān)于Android手勢(shì)處理的相關(guān)知識(shí)點(diǎn),如有不足或者錯(cuò)誤的地方請(qǐng)?jiān)谙路街刚?。我們需要多看更需要多寫,只有不斷學(xué)習(xí),不斷進(jìn)步才能不被淘汰。