判断是否滑动
//获取最小滑动距离的常量,和设备有关。小于这个值,认定不是滑动。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
新闻热点
疑难解答