2010-08-24 171 views
7

我对Android应用程序开发非常陌生,我一直在使用Android的SimpleOnGestureListener和ViewFlipper进行滑动手势。有3个ViewFlipper子项,每个子项都是一个ScrollView。当活动加载时,它们都会动态填充,并且在此之后它们不会更改。 ScrollView是SimpleOnGestureListeners的附件。当滚动条太短而无法滚动时,Scrollview不会滑动

下面是我使用的布局:
+ ViewFlipper
++滚动型(X3,每个页面,每个具有以下:)
+++的LinearLayout(垂直)
++++ TextView的
++++ TableLayout(动态填充W/TableRows)
++++查看

我扩展了通用教程代码,你可以找到任何地方在线onFling方法,它的伟大工程 - 除了当其中一个ScrollViews没有足够的内容进行滚动湖

我已经缩小了问题的范围,通过在SimpleOnGestureListener的每个方法上重写和调用super来添加打印到日志来触摸检测。

当我在滚动的页面上滑动时,我会在onScroll的“onScroll”中得到一些“onClick”中的内容。“在页面上太短而无法滚动时,我会在onShowPress中”onClick“ “onLongPress”,这只是当我触摸内容太短的scrollview的孩子 - 如果我碰别处我根本没有得到任何事件。

想法是什么问题,或者如何检测滑动手势,无论ScrollView有多大?

编辑:我已经确定,当我在Android 2.2模拟器上运行此操作时,与我一直使用的Android 2.1u1 DroidX仿真器相反,它会消失。这在多个环境中是可重现的。


我对此有更多的了解;看起来好像onInterceptTouchEvent没有为每个运动事件调用,当滚动视图包含在鳍状肢(或WorkspaceView)中时。

特别是,我发现在修改另一个视图类来解决这个同样的问题的行为(这是不是唯一的脚蹼)如下 - 注意,这是Android 2.1的只有:

如果滚动视图足够长的时间可以滚动,ACTION_DOWN运动事件被ScrollView捕获,并且每个后续的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的修改,在对谷歌代码雄的视图项目中发现,现在这里:Horizontal "tab"ish scroll between views)。在我们收到一个移动事件的情况下,我们正在滚动(这只发生在我们故意选择拦截它的情况下 - 即它被设置在拦截函数中,所以我们已经进入拦截函数),我们执行我们渴望的举动行为。如果我们在这里收到一个移动事件并且我们没有滚动,那么我们通过onIntercept返回事件,然后看看我们现在是否设置为滚动。如果是这样,我们执行该操作。

这不是优雅,但它的作品!

回答

7

我需要创建一个扩展的滚动型的新类,并用这样的:

@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

尝试在您的布局xml中为每个ScrollView s设置android:fillViewport="true"。这告诉ScrollView是因为它是包含在视图大

+0

它被设置为所有的孩子。我甚至直接复制和粘贴XML在http://www.curious-creature.org/2010/08/15/scrollviews-handy-trick/?utm_source=feedburner&utm_medium=feed&utm_campaign=Feed:+PlanetAndroidCom+(Planet+Android)和尝试它作为一个孩子的看法。经过一番捣鼓之后,我设法让它们都填满了视口。但是即使他们这样做,也没有回调的机会。到目前为止,没有滚动条=没有onFling。 – 2010-08-24 23:39:39