在ScrollView的父级中没有检测到水平滑动

可能重复:
手势检测和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; } } 

Solutions Collecting From Web of "在ScrollView的父级中没有检测到水平滑动"

如果您希望整个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 ) { // Check movement along the Y-axis. If it exceeds SWIPE_MAX_OFF_PATH, // then dismiss the swipe. if( Math.abs( e1.getY() - e2.getY() ) > SWIPE_MAX_OFF_PATH ) return false; // Swipe from right to left. // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) // and a certain velocity (SWIPE_THRESHOLD_VELOCITY). if( e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs( velocityX ) > SWIPE_THRESHOLD_VELOCITY ) { next(); return true; } // Swipe from left to right. // The swipe needs to exceed a certain distance (SWIPE_MIN_DISTANCE) // and a certain velocity (SWIPE_THRESHOLD_VELOCITY). 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 ) { // TouchEvent dispatcher. if( gestureDetector != null ) { if( gestureDetector.onTouchEvent( ev ) ) // If the gestureDetector handles the event, a swipe has been // executed and no more needs to be done. return true; } return super.dispatchTouchEvent( ev ); } @Override public boolean onTouchEvent( MotionEvent event ) { return gestureDetector.onTouchEvent( event ); } protected abstract void previous(); protected abstract void next(); } 

您只需在扩展SwipeActivity之后实现next()previous()方法SwipeActivity

我不得不补充

 @Override public boolean dispatchTouchEvent(MotionEvent ev){ super.dispatchTouchEvent(ev); return productGestureDetector.onTouchEvent(ev); } 

在你的activity类中添加这个方法,就像onCreate方法一样使用swiper。

android的事件顺序是这样的

用户执行一些动作 – >动作传递给父 – >如果父处理动作,则动作被消耗 – >否则动作传递给子 – >如果孩子处理动作,则动作被消耗 – >否则动作传递上

这个过程一直持续到行动被消耗或者所有的孩子都已经接受了这个行动,他们都没有处理过

要检测滚动视图中的水平滑动并将其传递给子对象,而不是滚动视图,则需要截取事件。

即用户执行一些操作 – >动作传递给父 – >如果横向滑动传递给子 – >否则有滚动视图处理动作

要做到这一点(如此处排在最前面的答案: ScrollView Touch Handling内的Horizo​​ntalScrollView ),在滚动视图中使用手势检测器,仅用于检测手势是水平还是垂直。

如果手势是水平的,那么我们要拦截事件并将其传递给孩子。

你需要创build一个自定义的滚动视图,然后在那里实现一个手势检测器,并从onInterceptTouch()调用它。 通过在这里返回true或false,我们可以说在这里是否消耗事件,所需的一切都在上面的链接中。