GestureDetector 和ScrollView问题

GestureDetector手势识别监听和GestureDetector的冲突

当手势识别和ScrollView相遇的时候 会导致 手势识别没有效果
或者说 效果很差 因为两个组件之间有冲突导致

举个栗子:

我设置了一个手势监听器来检测布局上的水平滑动。当布局是LinearLayout时,可以正确检测到滑动,但是当它是ScrollView时,则不是。我猜这个手势首先被ScrollView检测到,并没有传播给它的上级!

 <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
                  android:layout_width="fill_parent"
                  android:layout_height="fill_parent"
                  android:orientation="vertical">

        <ImageView
            android:layout_width="320dp"
            android:layout_height="30dp"
            android:src="@drawable/header"/>

        <ScrollView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content">
            <!-- stuff -->
        </ScrollView>
    </LinearLayout>

我将下面的侦听器设置为我的布局:

class ProductGestureListener extends SimpleOnGestureListener {

    @Override
    public boolean onDown(MotionEvent e) {
        return true;
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

        final int SWIPE_MIN_DISTANCE = 120;
        final int SWIPE_MAX_OFF_PATH = 250;
        final int SWIPE_THRESHOLD_VELOCITY = 200;            

        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH)
                return false;
            if(e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE &&
             Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {                   
                // show previous item
            }  else if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && 
            Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
               // show next item
            }
        } catch (Exception e) {
        }           
        return false;
    }
}

解决的方法

其中一个解决方法是这样的:让整体Activity可以水平滑动,可以使用以下内容作为超类Activity

public abstract class SwipeActivity extends Activity {
   private static final int SWIPE_MIN_DISTANCE = 120;
   private static final int SWIPE_MAX_OFF_PATH = 250;
   private static final int SWIPE_THRESHOLD_VELOCITY = 200;
   private GestureDetector gestureDetector;

   @Override
   protected void onCreate( Bundle savedInstanceState ) {
      super.onCreate( savedInstanceState );
      gestureDetector = new GestureDetector( new SwipeDetector() );
   }

   private class SwipeDetector extends SimpleOnGestureListener {
      @Override
      public boolean onFling( MotionEvent e1, MotionEvent e2,
      float velocityX, float velocityY ) {

         //检查y轴的运动。如果它超过SWIPE_MAX_OFF_PATH,
         //取消滑动
         if( Math.abs( e1.getY() - e2.getY() ) > SWIPE_MAX_OFF_PATH )
            return false;

         // 从右往左滑动
         // 滑动需要超过一定的距离 (SWIPE_MIN_DISTANCE) 
         // 和速率 (SWIPE_THRESHOLD_VELOCITY).
         if( e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs( velocityX ) > 
         SWIPE_THRESHOLD_VELOCITY ) {
            next();
            return true;
         }

         // 从左往右滑动
         // 原理同上
         if( e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs( velocityX ) >  
         SWIPE_THRESHOLD_VELOCITY ) {
            previous();
            return true;
         }
         return false;
      }
   }

   @Override
   public boolean dispatchTouchEvent( MotionEvent ev ) {      
      if( gestureDetector != null ) {
         if( gestureDetector.onTouchEvent( ev ) )
            // 执行滑动事件
            return true;
      }
      return super.dispatchTouchEvent( ev );
   }

   @Override
   public boolean onTouchEvent( MotionEvent event ) {
      return gestureDetector.onTouchEvent( event );
   }

   protected abstract void previous();

   protected abstract void next();
}

最后你只需要实现相应的方法next()和previous()

这样就可以实现你想要的效果了 可以识组件别左右滑动 亦或是自定义View的左右滑动!!
如有帮助请多点赞!

猜你喜欢

转载自blog.csdn.net/life_s/article/details/80535056
今日推荐