与ScrollView一起更改滑动/抓取选项卡?

时间:2011-02-24 09:55:40

标签: android scrollview swipe

我在这个特定问题上找到的最好的(虽然我没有使用图库):ScrollView and Gallery interfering - 虽然没有给出具体答案。显然,我的实现并没有使用Gallery。

跳转到有趣部分的下一个粗体部分

所以我得到了Fling / Swipe / Flick /你想要在我的应用程序上调用它的时候。灵感来自几个不同的地方,其中一些是Stack Overflow(Fling gesture detection on grid layout),Code Shogun(http://www.codeshogun.com/blog/2009/04/16/how-to-implement-swipe-action-in-android/)和开发Android(http://developingandroid.blogspot.com/2009/09/implementing-swipe-gesture.html)的“基本手势检测” ,但我不在我的应用程序中使用ViewFlipper。当发生甩尾时,我只需更换标签(在末端缠绕)。

现在,我的一些标签包含ScrollViews。这些ScrollViews显然会响应向上/向下滚动,以便让您查看其中的所有数据,这并不奇怪。 问题是看起来这些ScrollViews的“滚动”功能会覆盖我的手势。我不能在ScrollView内部滚动(滚动得很好),但它在它们之外完美无缺地工作(在同一个选项卡上,在TableRow等其他视图上)。

我也快速查看了http://blog.velir.com/index.php/2010/11/17/android-snapping-horizontal-scroll/,它提供了一种实现Horizo​​ntalScrollView的方法。但它仍然通过扩展SimpleOnGestureListener(并覆盖onFling)的类来处理手势,这与我的实现相同(这使我相信它不会真正有用)。 来自Google的ScrollView的源代码:http://google.com/codesearch/p?hl=en#uX1GffpyOZk/core/java/android/widget/ScrollView.java&d=3

有没有办法让我的Swipe和ScrollView的实现毫不费力地协同工作?

我猜这是问题所在。 ScrollView.java还使用了一个名为onTouchEvent的方法和onTouchEvent for Activity状态的文档:

  

“触摸屏事件发生时调用   不受任何意见处理   它。这对处理最有用   触摸发生在外面的事件   你的窗户边界,没有   查看接收它。“

所以ScrollView会“覆盖”它 - 我该怎么办?有没有办法确保两者都被检查?我的onTouchEvent在ScrollView处理onTouchEvent时没有被击中:

@Override
/** Used for swipe gestures */
public boolean onTouchEvent(MotionEvent event) {
    if (gestureDetector.onTouchEvent(event))
        return true;
    else
        return false;
}

下面更一般的源代码,它可能不是非常重要。我的Tabs类中的gestureDetector及其关联的侦听器:

    // Gestures
    gestureDetector = new GestureDetector(new MyGestureDetector());
    gestureListener = new View.OnTouchListener() {
        @Override
        public boolean onTouch(View v, MotionEvent event) {
            if (gestureDetector.onTouchEvent(event)) {
                return true;
            }
            return false;
        }
    };

我的手势类是我的Tabs类的嵌套类(扩展了TabActivity) - 它与你在这个主题上找到的任何其他代码相同:

/** GestureDetector used to swipe between classes */
class MyGestureDetector extends SimpleOnGestureListener {
    TabHost tabHost = getTabHost(); 

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
        try {
            if (Math.abs(e1.getY() - e2.getY()) > SWIPE_MAX_OFF_PATH) return false;
            if (e1.getX() - e2.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                // my tab code
                return true;
            } else if (e2.getX() - e1.getX() > SWIPE_MIN_DISTANCE && Math.abs(velocityX) > SWIPE_THRESHOLD_VELOCITY) {
                // my tab code
                return true;
            }
        } catch (Exception e) {
            Log.e("MyGestureDetector onFling", e.toString());
        }
        return false;
    }
}

3 个答案:

答案 0 :(得分:18)

我建议您查看Google I / O 2010应用源代码,因为他们的FlingableTabHost实现似乎已经解决了这个问题:

http://iosched.googlecode.com/svn/trunk/src/com/google/android/apps/iosched/ui/ScheduleActivity.java

我认为关键在于扩展TabHost并覆盖其onInterceptTouchEvent方法。

答案 1 :(得分:0)

为了解决我遇到的类似问题,我遇到了这个问题:

  

eventsInterceptionEnabled:当设置为true时,此属性会告诉叠加层在知道用户正在绘制手势时立即从其子级中窃取事件。当叠加层下方有可滚动视图时,这非常有用,以避免在用户绘制手势时滚动基础子项

Android Dev site开始,它讨论了在布局文件的<android.gesture.GestureOverlayView> Root中使用此属性。

答案 2 :(得分:0)

对于它的价值,我发现onFling方法非常不可靠。我重写了SimpleGestureDetector中的onScroll方法,并将onInterceptTouchEvent定义为:

@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
    //Call super first because it does some hidden motion event handling
    boolean result = super.onInterceptTouchEvent(ev);
    if (this.mGestureScanner.onTouchEvent(ev)) return true;
    return result;
}