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); } };