Android开发之手势滑动(滑动手势监听)详解
在Android应用中,经常需要手势滑动操作,比如上下滑动,或左右方向滑动,处理手势滑动通常有两种方法:一种是单独实现setOnTouchListener监听器来,另一种是构建手势探测器
第一种方法,就是在要实现滑动的View中,实现OnTouchListener监听事件,然后判断KeyDonw和KeyUp 直接的位置距离来判断滑动方向,核心实现代码如下:
/** * 设置上下滑动作监听器 * @author jczmdeveloper */ private void setGestureListener(){ myView.setOnTouchListener(new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub switch (event.getAction()) { case MotionEvent.ACTION_DOWN: mPosX = event.getX(); mPosY = event.getY(); break; case MotionEvent.ACTION_MOVE: mCurPosX = event.getX(); mCurPosY = event.getY(); break; case MotionEvent.ACTION_UP: if (mCurPosY - mPosY > 0 && (Math.abs(mCurPosY - mPosY) > 25)) { //向下滑動 } else if (mCurPosY - mPosY < 0 && (Math.abs(mCurPosY - mPosY) > 25)) { //向上滑动 collapse(); } break; } return true; } }); }
第二种方法:就是构建手势探测器,如GestureDetector mygesture = new GestureDetector(this);,然后在onFling方法中根据MotionEvent的两个参数的 按下和滑动以及放开的位置和距离来判断滑动方向以及滑动速度等的。要构建GestureDetector,必须要和OnTouchListener一起使用,因为必须设置Touch监听,核心实现实例如下:
import android.content.Context; import android.util.AttributeSet; import android.view.GestureDetector; import android.view.GestureDetector.OnGestureListener; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.View.OnTouchListener; import android.view.animation.Animation; import android.view.animation.AnimationUtils; import android.widget.FrameLayout; import android.widget.LinearLayout; public class TagScrollView extends FrameLayout implements OnTouchListener, OnGestureListener{ private float mPosX, mPosY, mCurPosX, mCurPosY; private static final int FLING_MIN_DISTANCE = 20;// 移动最小距离 private static final int FLING_MIN_VELOCITY = 200;// 移动最大速度 //构建手势探测器 GestureDetector mygesture = new GestureDetector(this); public TagScrollView(Context context) { this(context, null); } public TagScrollView(Context context, AttributeSet attrs) { this(context, attrs, 0); } public TagScrollView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); //setGestureListener(); //设置Touch监听 this.setOnTouchListener(this); //允许长按 this.setLongClickable(true); } @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return mygesture.onTouchEvent(event); } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub // e1:第1个ACTION_DOWN MotionEvent // e2:最后一个ACTION_MOVE MotionEvent // velocityX:X轴上的移动速度(像素/秒) // velocityY:Y轴上的移动速度(像素/秒) // X轴的坐标位移大于FLING_MIN_DISTANCE,且移动速度大于FLING_MIN_VELOCITY个像素/秒 //向 if (e1.getY() - e2.getY() > FLING_MIN_DISTANCE){ // && Math.abs(velocityX) > FLING_MIN_VELOCITY) { collapse(); } //向上 if (e2.getY() - e1.getY() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) { } return false; } }
应用实例如下:
比如对一个ListView进行手势滑动监听的实现如下:
private float mPosX, mPosY, mCurPosX, mCurPosY;//记录mListViewDevice 滑动的位置 private static final int FLING_MIN_DISTANCE = 20;//mListView 滑动最小距离 private static final int FLING_MIN_VELOCITY = 200;//mListView 滑动最大速度 /** * @author jczmdeveloper * @desp mListView 的手势监听 */ private OnGestureListener listViewGestureListener = new OnGestureListener() { @Override public boolean onSingleTapUp(MotionEvent e) { // TODO Auto-generated method stub return false; } @Override public void onShowPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { // TODO Auto-generated method stub return false; } @Override public void onLongPress(MotionEvent e) { // TODO Auto-generated method stub } @Override public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { // TODO Auto-generated method stub //向上滑动 if (e1.getY() - e2.getY() > FLING_MIN_DISTANCE) { // && Math.abs(velocityX) > FLING_MIN_VELOCITY) { if (mListViewDevice.getLastVisiblePosition() == mListView .getCount() - 1) { //do something } } // 向下滑动 if (e2.getY() - e1.getY() > FLING_MIN_DISTANCE && Math.abs(velocityX) > FLING_MIN_VELOCITY) { } return false; } @Override public boolean onDown(MotionEvent e) { // TODO Auto-generated method stub return false; } }; /** * @author jczmdeveloper * @desp mListView 的手势探测器 */ GestureDetector listViewGesture = new GestureDetector(listViewGestureListener); /** * @author jczmdeveloper * @desp mListView 的触摸监听 */ private OnTouchListener listViewOnTouchListener = new OnTouchListener() { @Override public boolean onTouch(View v, MotionEvent event) { // TODO Auto-generated method stub return listViewDeviceGesture.onTouchEvent(event); } };