我对Android应用程序开发还很陌生,我一直在用Android的simpleongestureelistener和ViewFlipper玩刷卡手势。ViewFlipper有3个子级,每个子级都是一个ScrollView。当活动加载时,它们都是动态填充的,并且在加载之后不会改变。ScrollView是SimpleNogestureListeners的附件。
以下是我使用的布局:
+视图翻转器
++ScrollView(x3,每页一个,每个带有以下内容:)
+++线性布局(垂直)
++++文本视图
我用你在网上任何地方都能找到的常用教程代码扩展了onFling方法,它工作得很好——除非其中一个ScrollViews包含的内容不够滚动。
我已经将问题缩小到了触摸检测,通过重写并调用SimpleOnGestureListener的每个方法中的super,将打印添加到日志中。
在内部
太短的滚动视图的孩子们——如果我触摸其他地方,我就根本看不到任何事件。
关于什么是错的,或者不管滚动视图有多大如何检测滑动手势的想法?
编辑:我已经确定,当我在android2.2模拟器上运行它时,与我一直使用的android2.1u1droidx模拟器相反,它会消失。这在多种环境下都是可重复的。
我对此有更深入的了解;似乎当scrollview包含在flipper(或WorkspaceView)中时,不会为每个运动事件调用onInterceptTouchEvent。
如果scrollview足够长,可以滚动,则scrollview会捕获ACTION\u DOWN motion事件,并且每个后续的ACTION\u MOVE事件都会经过flipper的InterceptTouchEvent,在那里它会被拦截并得到适当的处理。在android2.2中,无论滚动长度如何,都会发生这种行为。
回到2.1:如果scrollview不够长,无法滚动,那么ACTION\u DOWN motion事件是
不
跳过
onInterceptTouchEvent函数,直接转到onTouchEvent函数!
我解决这个问题的方法是利用onTouchEvent中的ACTION\u MOVE事件功能,并将其重构为自己的方法。这样,如果onTouchEvent检测到事件以前未经处理,我就可以让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;
这是从工作空间视图.java(Android的工作区.java,在谷歌代码上的andro views项目中找到,现在这里:
Horizontal "tab"ish scroll between views
). 如果我们收到一个move事件,并且我们正在滚动(只有当我们故意选择截取它时才会发生——也就是说,它是在intercept函数中设置的,所以我们已经去过intercept函数)我们执行我们想要的移动行为。如果我们在这里收到一个move事件,而我们没有滚动,那么我们通过onIntercept将事件发送回来,然后查看是否现在设置为滚动。如果是这样,我们就执行这个动作。
虽然不优雅,但很管用!