View的上下左右
image
1、getX\getY\getTop\getBottom\x\y\translationX\translationY

image
2、手指觸摸時(shí),相對(duì)屏幕的x,y坐標(biāo)

image
View的寬高
單位px

image
MotionEvent (手指觸摸產(chǎn)生的事件)
MotionEvent是手觸摸屏幕后產(chǎn)生的一系列的事件,主要包括:點(diǎn)擊、移動(dòng)、離開(kāi)等動(dòng)作

image
VelocityTracker(手指在屏幕上的滑動(dòng)速度)
VelocityTraker用來(lái)獲取手指滑動(dòng)時(shí)的水平速度和垂直速度。
計(jì)算水平和垂直滑動(dòng)速度
VelocityTracker velocityTracker;
private void init(){
velocityTracker = VelocityTracker.obtain();
}
@Override
public boolean onTouchEvent(MotionEvent e) {
velocityTracker.addMovement(e);
switch (e.getAction()){
cker.computeCurrentVelocity(1000);
float xVelocity = velocityTracker.getXVelocity();
float yVelocity = velocityTracker.getYVelocity();
velocityTracker.clear();
velocityTracker.recycle();
break;
default:break;
}
return true;
通過(guò)VelocityTracker.clear重制回收內(nèi)存
GeastureDetecor手勢(shì)檢測(cè)
手勢(shì)檢測(cè)用戶檢測(cè)用戶的單擊、長(zhǎng)按、雙擊、滑動(dòng)等行為。她通過(guò)GeatureDetector的onGestureListener和OnDoubleTapListener接口實(shí)現(xiàn)監(jiān)聽(tīng)。
| :onGestureListener | 描述 |
|---|---|
| onDown(MotionEvent e) | 用戶按下屏幕,由ACTION_DOWN觸發(fā) |
| nFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) | e1:第1個(gè)ACTION_DOWN MotionEvent e2:最后一個(gè)ACTION_MOVE MotionEvent velocityX:X軸上的移動(dòng)速度,像素/秒 velocityY:Y軸上的移動(dòng)速度,像素/秒 |
| onLongPress(MotionEvent e) | 長(zhǎng)按觸摸屏,超過(guò)一定時(shí)長(zhǎng),就會(huì)觸發(fā)這個(gè)事件 觸發(fā)順序: onDown->onShowPress->onLongPress |
| onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) | 在屏幕上拖動(dòng)事件。無(wú)論是用手拖動(dòng)view,或者是以拋的動(dòng)作滾動(dòng),都會(huì)多次觸發(fā),這個(gè)方法在ACTION_MOVE動(dòng)作發(fā)生時(shí)就會(huì)觸發(fā) 滑屏:手指觸動(dòng)屏幕后,稍微滑動(dòng)后立即松開(kāi) onDown-----》onScroll----》onScroll----》onScroll----》………----->onFling 拖動(dòng) onDown------》onScroll----》onScroll------》onFiling |
| nShowPress(MotionEvent e) | 如果是按下的時(shí)間超過(guò)瞬間,而且在按下的時(shí)候沒(méi)有松開(kāi)或者是拖動(dòng)的,那么onShowPress就會(huì)執(zhí)行 |
| onSingleTapUp(MotionEvent e) | 一次單獨(dú)的輕擊抬起操作,也就是輕擊一下屏幕,立刻抬起來(lái),才會(huì)有這個(gè)觸發(fā),當(dāng)然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以也就不會(huì)觸發(fā)這個(gè)事件 觸發(fā)順序: 點(diǎn)擊一下非??斓模ú换瑒?dòng))Touchup: onDown->onSingleTapUp->onSingleTapConfirmed 點(diǎn)擊一下稍微慢點(diǎn)的(不滑動(dòng))Touchup: onDown->onShowPress->onSingleTapUp->onSingleTapConfirmed |
可見(jiàn),無(wú)論是滑屏,還是拖動(dòng),影響的只是中間OnScroll觸發(fā)的數(shù)量多少而已,最終都會(huì)觸發(fā)onFling事件!
| onDoubleTapListener | |
|---|---|
| onDoubleTap(MotionEvent e) | 雙擊,不與onSingleTapConfirmed共存 |
| onDoubleTapEvent(MotionEvent e) | 雙擊行為。雙擊期間 ACTION_DOWN, AVTION_MOVE,ACTION_UP都會(huì)觸發(fā)此回調(diào)。 |
| onSingleTapConfirmed(MotionEvent e) | 嚴(yán)格的單擊行為 |
通過(guò)GestureDetecor監(jiān)聽(tīng)手勢(shì):
1、首先要實(shí)現(xiàn)一個(gè)GeastureDetetoc對(duì)象。
2、實(shí)現(xiàn)GestureDetector.OnGestureListener的接口
3、在View的onTouchEvent方法中實(shí)現(xiàn):
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event)
Demo
public class MainActivity extends Activity implements OnTouchListener{
private GestureDetector mGestureDetector;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGestureDetector = new GestureDetector(new gestureListener()); //使用派生自O(shè)nGestureListener
TextView tv = (TextView)findViewById(R.id.tv);
tv.setOnTouchListener(this);
tv.setFocusable(true);
tv.setClickable(true);
tv.setLongClickable(true);
}
/*
* 在onTouch()方法中,我們調(diào)用GestureDetector的onTouchEvent()方法,將捕捉到的MotionEvent交給GestureDetector
* 來(lái)分析是否有合適的callback函數(shù)來(lái)處理用戶的手勢(shì)
*/
public boolean onTouch(View v, MotionEvent event) {
return mGestureDetector.onTouchEvent(event);
}
private class gestureListener implements GestureDetector.OnGestureListener{
// 用戶輕觸觸摸屏,由1個(gè)MotionEvent ACTION_DOWN觸發(fā)
public boolean onDown(MotionEvent e) {
Log.i("MyGesture", "onDown");
Toast.makeText(MainActivity.this, "onDown", Toast.LENGTH_SHORT).show();
return false;
}
/*
* 用戶輕觸觸摸屏,尚未松開(kāi)或拖動(dòng),由一個(gè)1個(gè)MotionEvent ACTION_DOWN觸發(fā)
* 注意和onDown()的區(qū)別,強(qiáng)調(diào)的是沒(méi)有松開(kāi)或者拖動(dòng)的狀態(tài)
*
* 而onDown也是由一個(gè)MotionEventACTION_DOWN觸發(fā)的,但是他沒(méi)有任何限制,
* 也就是說(shuō)當(dāng)用戶點(diǎn)擊的時(shí)候,首先MotionEventACTION_DOWN,onDown就會(huì)執(zhí)行,
* 如果在按下的瞬間沒(méi)有松開(kāi)或者是拖動(dòng)的時(shí)候onShowPress就會(huì)執(zhí)行,如果是按下的時(shí)間超過(guò)瞬間
* 拖動(dòng)了,就不執(zhí)行onShowPress。
*/
public void onShowPress(MotionEvent e) {
Log.i("MyGesture", "onShowPress");
Toast.makeText(MainActivity.this, "onShowPress", Toast.LENGTH_SHORT).show();
}
// 用戶(輕觸觸摸屏后)松開(kāi),由一個(gè)1個(gè)MotionEvent ACTION_UP觸發(fā)
///輕擊一下屏幕,立刻抬起來(lái),才會(huì)有這個(gè)觸發(fā)
//從名子也可以看出,一次單獨(dú)的輕擊抬起操作,當(dāng)然,如果除了Down以外還有其它操作,那就不再算是Single操作了,所以這個(gè)事件 就不再響應(yīng)
public boolean onSingleTapUp(MotionEvent e) {
Log.i("MyGesture", "onSingleTapUp");
Toast.makeText(MainActivity.this, "onSingleTapUp", Toast.LENGTH_SHORT).show();
return true;
}
// 用戶按下觸摸屏,并拖動(dòng),由1個(gè)MotionEvent ACTION_DOWN, 多個(gè)ACTION_MOVE觸發(fā)
public boolean onScroll(MotionEvent e1, MotionEvent e2,
float distanceX, float distanceY) {
Log.i("MyGesture22", "onScroll:"+(e2.getX()-e1.getX()) +" "+distanceX);
Toast.makeText(MainActivity.this, "onScroll", Toast.LENGTH_LONG).show();
return true;
}
// 用戶長(zhǎng)按觸摸屏,由多個(gè)MotionEvent ACTION_DOWN觸發(fā)
public void onLongPress(MotionEvent e) {
Log.i("MyGesture", "onLongPress");
Toast.makeText(MainActivity.this, "onLongPress", Toast.LENGTH_LONG).show();
}
// 用戶按下觸摸屏、快速移動(dòng)后松開(kāi),由1個(gè)MotionEvent ACTION_DOWN, 多個(gè)ACTION_MOVE, 1個(gè)ACTION_UP觸發(fā)
public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
float velocityY) {
Log.i("MyGesture", "onFling");
Toast.makeText(MainActivity.this, "onFling", Toast.LENGTH_LONG).show();
return tr
參考:
https://developer.android.com/reference/android/view/GestureDetector.OnDoubleTapListener