滚动型和美术馆干扰 [英] ScrollView and Gallery interfering

查看:79
本文介绍了滚动型和美术馆干扰的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多ScrollViews每个占满整个屏幕组成的画廊。问题是ScrollViews'的onT​​ouchEvent返回true,因此prevent在DOM来处理相同的事件的任何其他视图(其在滚动型水平处理后吞咽)。其结果是,画廊已经不滚动。在另一方面,如果我重写的onTouchEvent是这样的:

I have a Gallery composed of many ScrollViews each of which occupies the whole screen. problem is the ScrollViews' onTouchEvent returns true and therefore prevent any other view in the DOM to handle the same event (which is swallowed after being processed at the ScrollView level). As a result the Gallery doesn't scroll anymore. On the other hand if I override onTouchEvent like this:

   @Override
   public boolean onTouchEvent(MotionEvent ev) {
      super.onTouchEvent(ev);
      return false; // <<<<<<<<<<<<<<<<<
   }   

然后图库收到对事件进行处理,但SrollView犯规滚动了。无论哪种方式,你输了!还是你?

then the Gallery receives its on event to process but the SrollView doesnt scroll anymore. Either way you lose! or do you?

问题听起来令人费解,但我相信如果u在过去的偶然发现它乌拉圭回合会直接辨识出它一个吓坏该死的!

problem sounds puzzling but I am sure if u stumbled upon it in the past u r gonna recognize it straight away as it a freaking damn one!

感谢

推荐答案

下面是我尝试的画廊与垂直的作品 ScrollViews

Here's my attempt at gallery that works with vertical ScrollViews.

它使用自己的 GestureDetector 的实例,并与 MotionEvents 饲料从 onInterceptTouchEvent

It uses its own instance of GestureDetector and feeds it with MotionEvents from onInterceptTouchEvent.

在手势检测识别滚动,我们判断它是否是水平或垂直并且直到动作完成的方向锁定。这样就避免了对角滚动。

When gesture detector recognizes a scroll, we determine whether it's horizontal or vertical and lock on the direction until the gesture is finished. This avoids diagonal scrolling.

如果它是一个水平滚动, onInterceptTouchEvent 将返回true,以便将来移动事件去继承Gallery.onTouchEvent <$ C C $>做实际的滚动。

If it's a horizontal scroll, onInterceptTouchEvent will return true so that future motion events go to inherited Gallery.onTouchEvent to do the actual scrolling.

图库自己的手势检测器( mGestureDetector Gallery.java )并没有得到所有运动事件,因此有时会报告,导致画廊跳来跳去巨大突然滚动。我已经投入了一个讨厌的黑客工具,放弃这些。

Gallery's own gesture detector (mGestureDetector in Gallery.java) doesn't get all motion events and thus sometimes reports huge sudden scrolls that cause gallery to jump around. I've put in a a nasty hack that discards those.

在code:

import android.content.Context;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.widget.Gallery;

public class BetterGallery extends Gallery {
    /* This gets set when we detect horizontal scrolling */
    private boolean scrollingHorizontally = false;

    /* This gets set during vertical scrolling. We use this to avoid detecting
     * horizontal scrolling when vertical scrolling is already in progress
     * and vice versa. */
    private boolean scrollingVertically = false;

    /* Our own gesture detector, Gallery's mGestureDetector is private.
     * We'll feed it with motion events from `onInterceptTouchEvent` method. */
    private GestureDetector mBetterGestureDetector;

    public BetterGallery(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mBetterGestureDetector = new GestureDetector(new BetterGestureListener());
    }

    public BetterGallery(Context context, AttributeSet attrs) {
        super(context, attrs);
        mBetterGestureDetector = new GestureDetector(new BetterGestureListener());
    }

    public BetterGallery(Context context) {
        super(context);
        mBetterGestureDetector = new GestureDetector(new BetterGestureListener());
    }

    @Override
    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
            float velocityY) {
        // Limit velocity so we don't fly over views
        return super.onFling(e1, e2, 0, velocityY);
    } 

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        // Documentation on this method's contract:
        // http://developer.android.com/reference/android/view/ViewGroup.html#onInterceptTouchEvent(android.view.MotionEvent)

        // Reset our scrolling flags if ACTION_UP or ACTION_CANCEL
        switch (ev.getAction()) {
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            scrollingHorizontally = false;
            scrollingVertically = false;
        }       

        // Feed our gesture detector
        mBetterGestureDetector.onTouchEvent(ev);

        // Intercept motion events if horizontal scrolling is detected
        return scrollingHorizontally;
    }


    @Override
    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
        // Hack: eat jerky scrolls caused by stale state in mGestureDetector
        // which we cannot directly access
        if (Math.abs(distanceX) > 100) return false;

        return super.onScroll(e1, e2, distanceX, distanceY);
    }


    @Override
    public boolean onTouchEvent(MotionEvent event) {
        // Reset our scrolling flags if ACTION_UP or ACTION_CANCEL
        switch(event.getAction()) {
        case MotionEvent.ACTION_UP:
        case MotionEvent.ACTION_CANCEL:
            scrollingHorizontally = false;
            scrollingVertically = false;
        }

        super.onTouchEvent(event);
        return scrollingHorizontally;
    }

    private class BetterGestureListener implements GestureDetector.OnGestureListener {

        @Override
        public boolean onDown(MotionEvent arg0) {
            return false;
        }

        @Override
        public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2, float arg3) {
            return false;
        }

        @Override
        public void onLongPress(MotionEvent arg0) {
        }

        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            if (scrollingHorizontally || scrollingVertically) {
                // We already know we're scrolling, ignore this callback.
                // This avoids changing scrollingHorizontally / scrollingVertically
                // flags mid-scroll.
                return false;
            }

            scrollingHorizontally |= Math.abs(distanceX) > Math.abs(distanceY);
            // It's a scroll, and if it's not horizontal, then it has to be vertical
            scrollingVertically = !scrollingHorizontally;

            return false;
        }

        @Override
        public void onShowPress(MotionEvent arg0) {

        }

        @Override
        public boolean onSingleTapUp(MotionEvent arg0) {
            return false;
        }
    }
}

警告:单词更好类的名字,很可能误导

Warning: word "Better" in class name is likely misleading!

更新:

忘了提,我还设置了活动转发了的onTouchEvent 来画廊:

Forgot to mention, I've also set the activity to forward its onTouchEvent to gallery:

@Override
public boolean onTouchEvent(MotionEvent event) {
    return mGallery.onTouchEvent(event);
}

更新2:

我做了一些改进,这code和把它挂在 到位桶。 还有一个示例应用程序。这表明,该部件有问题,ListView的为孩子: - /

I've made some improvements to this code and put it up on bitbucket. There's also an example app. It demonstrates that this widget has issues with ListView as child :-/

更新3:

图库切换到 Horizo​​ntalScrollView 作为基类为我的自定义部件。 <一href="http://cuu508.word$p$pss.com/2011/07/20/horizontal-scrolling-widget-based-on-horizontalscrollview/">More在这这里。甩工作,列表视图和ExpandableListViews儿童工作,在Android 1.6,2.2,2.3.4进行测试。它的行为是现在很接近谷歌的应用程序,海事组织。

Switched from Gallery to HorizontalScrollView as the base class for my custom widget. More on this here. Flings work, ListViews and ExpandableListViews as children work, tested on Android 1.6, 2.2, 2.3.4. Its behaviour is now quite close to that of Google apps, IMO.

更新4:

谷歌已经发布的<一href="http://android-developers.blogspot.com/2011/08/horizontal-view-swiping-with-viewpager.html">ViewPager!

这篇关于滚动型和美术馆干扰的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆