滚动视图太短而不能滚动时不滚动
我对Android应用程序开发相当陌生,并且我一直在使用Android的SimpleOnGestureListener和ViewFlipper使用滑动手势进行游戏。 有3个ViewFlipper子项,每个子项都是一个ScrollView。 当活动加载时,它们都会动态填充,并且在此之后它们不会更改。 ScrollView是SimpleOnGestureListeners的附件。
这是我正在使用的布局:
+ ViewFlipper
++ ScrollView(x3,每个页面一个,每个都有以下:)
+++ LinearLayout(垂直)
++++的TextView
++++ TableLayout(动态填充w / TableRows)
++++查看
我将onFling方法扩展为可以在网上任何地方找到的常用教程代码,并且它的效果很好 - 除非其中一个ScrollViews没有足够的内容进行滚动。
我通过重写和调用每个SimpleOnGestureListener的方法来添加一个print-to-log方法,从而缩小了问题的范围。
当我在滚动的页面上滑动时,我会在onScroll的“onScroll”中获得“inClick”中的所有内容。在页面上太短而无法滚动时,我会在onLongPress的onShowPress“”中获得“onClick” “,那只有当我触摸太短滚动视图的孩子中的内容时 - 如果我在其他地方触摸,我根本没有收到任何活动。
关于什么是错误的想法,或者无论ScrollView有多大,如何检测轻扫手势?
编辑:我已经确定,当我在Android 2.2模拟器上运行此功能时,与我一直使用的Android 2.1u1 DroidX仿真器相反,它会消失。 这在多个环境中是可重现的。
我对此有更多的了解; 看起来好像onInterceptTouchEvent没有为每个运动事件调用,当滚动视图包含在鳍状肢(或WorkspaceView)中时。
特别是,我在修改另一个视图类以修复这个非常相同的问题(它不是独特的脚蹼)时发现的行为如下所示 - 请注意,这仅适用于Android 2.1:
如果scrollview足够长以便滚动,则ACTION_DOWN运动事件被ScrollView捕获,并且每个后续的ACTION_MOVE事件都会经过鳍状肢的onInterceptTouchEvent,在那里被截取并正确处理。 在android 2.2中,无论滚动长度如何,都会发生这种情况。
回到2.1:如果scrollview的长度不够滚动,ACTION_DOWN运动事件不会被scrollview捕获,而是返回到鳍状肢的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项目中找到,现在在这里:水平“标签”ish在视图之间滚动)。 在我们收到一个移动事件的情况下,我们正在滚动(这只发生在我们故意选择拦截它的情况下 - 即它被设置在拦截函数中,所以我们已经进入拦截函数),我们执行我们渴望的举动行为。 如果我们在这里收到一个移动事件并且我们没有滚动,那么我们通过onIntercept返回事件,然后看看我们现在是否设置为滚动。 如果是这样,我们执行该操作。
这不是优雅的,但它的作品!
我需要创建一个扩展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));
如果我理解正确),它不起作用,这是。
尝试在每个ScrollView
的布局xml中设置android:fillViewport="true"
。 这告诉ScrollView
与它所包含的视图一样大。