判斷是否滑動
//獲取最小滑動距離的常量,和設備有關。小于這個值,認定不是滑動。int mTouchSlop = ViewConfiguration.get(getContext()).getScaledTouchSlop();用于view的彈性滑動,實現過渡效果,不是瞬間完成,而是一定時間間隔內完成的。Scroller無法使view滑動,需要和view的computeScroll()方法配合使用才能實現這個功能。
創建Scroller的實例 調用startScroll()方法來初始化滾動數據并刷新界面 重寫computeScroll()方法,并在其內部完成平滑滾動的邏輯 Scroller mScroller= new Scroller(context); //緩慢滑動到指定位置 private void smoothScrollTo(int destX , int destY){ int scrollX=getScrollX(); int delta=destX-scrollX; mScroller.startScroll(scrollX,0,delta,1000); invalidate(); } @Override public void computeScroll() { //重寫computeScroll()方法,并在其內部完成平滑滾動的邏輯 ////判斷滾動是否還在繼續,true繼續,false結束 if (mScroller.computeScrollOffset()) { scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); invalidate(); } }三種構造方法:
GestureDetector gestureDetector=new GestureDetector(GestureDetector.OnGestureListener listener); GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.OnGestureListener listener); GestureDetector gestureDetector=new GestureDetector(Context context,GestureDetector.SimpleOnGestureListener listener);GestureDetector這個類對外提供了兩個接口和一個外部類 接口:OnGestureListener,OnDoubleTapListener 內部類:SimpleOnGestureListener 這個外部類,其實是兩個接口中所有函數的集成,它包含了這兩個接口里所有必須要實現的函數而且都已經重寫,但所有方法體都是空的;不同點在于:該類是static class,程序員可以在外部繼承這個類,重寫里面的手勢處理方法。
首先是聲明一個GestureDetector,然后重寫Button的onTouch函數,將觸屏事件交給GestureDetector處理。
public class MainActivity extends Activity { private Button mButton; private GestureDetector mGestureDetector; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mGestureDetector = new GestureDetector(this, new MyOnGestureListener()); mButton = (Button) findViewById(R.id.btn_textgesture); mButton.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { Log.i(getClass().getName(), "onTouch-----" + getActionName(event.getAction())); mGestureDetector.onTouchEvent(event); // 一定要返回true,不然獲取不到完整的事件 return true; } }); } private String getActionName(int action) { String name = ""; switch (action) { case MotionEvent.ACTION_DOWN: { name = "ACTION_DOWN"; break; } case MotionEvent.ACTION_MOVE: { name = "ACTION_MOVE"; break; } case MotionEvent.ACTION_UP: { name = "ACTION_UP"; break; } default: break; } return name; } class MyOnGestureListener extends SimpleOnGestureListener { @Override public boolean onSingleTapUp(MotionEvent e) { Log.i(getClass().getName(), "onSingleTapUp-----" + getActionName(e.getAction())); return false; } @Override public void onLongPress(MotionEvent e) { Log.i(getClass().getName(), "onLongPress-----" + getActionName(e.getAction())); } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { Log.i(getClass().getName(), "onScroll-----" + getActionName(e2.getAction()) + ",(" + e1.getX() + "," + e1.getY() + ") ,(" + e2.getX() + "," + e2.getY() + ")"); return false; } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { Log.i(getClass().getName(), "onFling-----" + getActionName(e2.getAction()) + ",(" + e1.getX() + "," + e1.getY() + ") ,(" + e2.getX() + "," + e2.getY() + ")"); return false; } @Override public void onShowPress(MotionEvent e) { Log.i(getClass().getName(), "onShowPress-----" + getActionName(e.getAction())); } @Override public boolean onDown(MotionEvent e) { Log.i(getClass().getName(), "onDown-----" + getActionName(e.getAction())); return false; } @Override public boolean onDoubleTap(MotionEvent e) { Log.i(getClass().getName(), "onDoubleTap-----" + getActionName(e.getAction())); return false; } @Override public boolean onDoubleTapEvent(MotionEvent e) { Log.i(getClass().getName(), "onDoubleTapEvent-----" + getActionName(e.getAction())); return false; } @Override public boolean onSingleTapConfirmed(MotionEvent e) { Log.i(getClass().getName(), "onSingleTapConfirmed-----" + getActionName(e.getAction())); return false; } } }推薦: 監聽滑動用onTouchEvent 監聽雙擊用GestureDetector
Android中實現view的更新有兩組方法,一組是invalidate,另一組是postInvalidate,其中前者是在UI線程自身中使用,而后者在非UI線程中使用。
OnTouchListener和onTouchEvent一樣都是view類里面的,都可以監聽事件的down、move、up,但一個是接口類,首字母大寫,一個是方法,首字母小寫,OnTouchListener優先級大于onTouchEvent,OnTouchListener接口要實現onTouch方法,當OnTouchListener實現方法onTouch返回true不會執行onTouchEvent,返回false才會執行onTouchEvent。
Android手勢監聽類GestureDetector的使用
用戶手勢檢測-GestureDetector使用詳解
android 事件處理機制之requestDisallowInterceptTouchEvent
新聞熱點
疑難解答