我对Android应用程序开发很陌生,而且我一直在使用Android的SimpleOnGestureListener和ViewFlipper进行滑动手势。 ViewFlipper有3个子节点,每个子节点都是ScrollView。它们都是在Activity加载时动态填充的,并且在此之后它们不会更改。 ScrollView是SimpleOnGestureListeners附加的位置。
这是我正在使用的布局:
+ ViewFlipper
++ ScrollView(x3,每页一个,每个都有以下:)
+++ LinearLayout(垂直)
++++的TextView
++++ TableLayout(动态填充w / TableRows)
++++查看
我使用你可以在网上任何地方找到的常用教程代码扩展了onFling方法,并且效果很好 - 除非其中一个ScrollViews没有足够的内容来滚动。
我已经通过覆盖和调用super来调整每个SimpleOnGestureListener的方法来将问题缩小到触摸检测,以添加打印到日志。
当我在滚动的页面上滑动时,我会在onFling中获得“in onClick”“in onScroll”中的内容等等。在一个太短而无法滚动的页面上,我在onShowPress中获得“in onClick” “在onLongPress中”,只有当我触摸内的太短的scrollview的孩子时 - 如果我触摸其他地方,我根本就没有事件。
关于什么是错误的想法,或者无论ScrollView有多大,如何检测滑动手势?
编辑:我已经确定当我在Android 2.2模拟器上运行时,与我一直在使用的Android 2.1u1 DroidX模拟器相反,它就消失了。这在多个环境中都是可重现的。
我对此有更深入的了解;似乎当滚动视图包含在翻转器(或工作区视图)中时,不会为每个动作事件调用onInterceptTouchEvent。
特别是,我在修改另一个视图类时修复了同样的问题(它不是鳍状肢独有的)时发现的行为如下 - 注意这只是Android 2.1:
如果滚动视图足够长以便滚动,则ScrollView会捕获ACTION_DOWN运动事件,并且每个后续的ACTION_MOVE事件都会通过脚蹼的onInterceptTouchEvent进行处理,并在其中进行相应的拦截和处理。在Android 2.2中,无论滚动长度如何,都会发生此行为。
返回2.1:如果滚动视图的滚动时间不够长,则滚动视图会捕获ACTION_DOWN运动事件 ,而是返回到鳍状肢的onTouchEvent。相同手势的所有后续ACTION_MOVE事件跳过 onInterceptTouchEvent函数并直接进入onTouchEvent函数!
我解决这个问题的方法是将onTouchEvent中的功能用于ACTION_MOVE事件并将其重构为自己的方法。通过这种方式,我可以在onTouchEvent上调用onInterceptTouchEvent,如果它检测到事件以前未处理过,则可以使用该功能。
case MotionEvent.ACTION_MOVE:
if (touchState == TOUCH_STATE_SCROLLING) {
handleScrollMove(ev);
} else {
// Log.d("workspace","caught a move touch event but not scrolling");
//NOTE: We will never hit this case in Android 2.2. This is to fix a 2.1 bug.
//We need to do the work of interceptTouchEvent here because we don't intercept the move
//on children who don't scroll.
Log.d("workspace","handling move from onTouch");
if(onInterceptTouchEvent(ev) && touchState == TOUCH_STATE_SCROLLING){
handleScrollMove(ev);
}
}
break;
这是来自WorkspaceView.java(Android的Workspace.java的修改,在google代码的andro-views项目中找到,现在在这里:Horizontal "tab"ish scroll between views)。在我们收到移动事件的情况下,我们正在滚动(只有当我们故意选择拦截它时才会发生 - 也就是说,它是在拦截函数中设置的,所以我们已经去过拦截功能)我们执行我们渴望的移动行为。如果我们在这里收到移动事件并且我们没有滚动,那么我们通过onIntercept重新发送事件,然后看看我们现在是否设置为滚动。如果是,我们会执行操作。
它不优雅,但它有效!
答案 0 :(得分:7)
我需要创建一个扩展ScrollView的新类,并使用它:
@Override
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
return gestureDetector.onTouchEvent(event);
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev){
gestureDetector.onTouchEvent(ev);
super.dispatchTouchEvent(ev);
return true;
}
我不知道为什么,但是如果我尝试在dispatchTouchEvent中返回任何真实的东西(理所当然就是
return (gestureDetector.onTouchEvent(ev) || super.dispatchTouchEvent(ev));
如果我理解得当,它不起作用,而且确实如此。
答案 1 :(得分:1)
尝试在每个android:fillViewport="true"
的布局xml中设置ScrollView
。这告诉ScrollView
与它所包含的视图一样大。
答案 2 :(得分:0)
有同样的问题。如果ScrollView
的子项太短而没有滚动条,则需要在其子项上拦截touch事件。