4

I've got a Horizontal Scroll View placed in ViewPager. The goal is to use only software triggered scrolling of Horizontal Scroll View. All the scrolling gestures should be handled by the view pager.

I already did it by creating a custom View Pager that intercepts all swipe gestures:

public class GreedyViewPager extends ViewPager {

    GestureDetector mGestureDetector;
    View.OnTouchListener mGestureListener;

    public GreedyViewPager(Context context) {
        super(context);
        initGestureDetector(context);
    }

    public GreedyViewPager(Context context, AttributeSet attributeSet) {
        super(context, attributeSet);
        initGestureDetector(context);
    }

    void initGestureDetector(Context context){
        mGestureDetector = new GestureDetector(context, new ScrollDetector());
        ViewConfiguration vc = ViewConfiguration.get(context);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        return super.onInterceptTouchEvent(ev) || mGestureDetector.onTouchEvent(ev);
    }

    class ScrollDetector extends SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            return true;
        }

        @Override
        public boolean onDoubleTap(MotionEvent e) {
            return true;
        }
    }
}

Unfortunately it doesn't work well with all devices, sometimes I have to swipe a coupe of times in order to go to the next position in the ViewPager.

Any idea how to make it better?

Hrqls
  • 2,944
  • 4
  • 34
  • 54
kmalmur
  • 2,809
  • 3
  • 29
  • 37
  • http://stackoverflow.com/questions/7814017/is-it-possible-to-disable-scrolling-on-a-viewpager – Android May 27 '14 at 12:53
  • http://stackoverflow.com/questions/8134336/disabling-enabling-paging-in-viewpager-in-android and another link is http://stackoverflow.com/questions/9650265/how-do-disable-paging-by-swiping-with-finger-in-viewpager-but-still-be-able-to-s may be this useful – Android May 27 '14 at 12:54
  • @Pragna I want to do something opposite, this solution locks ViewPager , I wan't the ViewPager to intercept all scroll events – kmalmur May 27 '14 at 13:17
  • Try this viewPager.setDescendantFocusability(ViewPager.FOCUS_BEFORE_DESCENDANTS); – Sripathi Jun 10 '14 at 08:38
  • @kmalmur Were you able to fix this? I'm facing the same issue today and focus_before_descendants is not working – jennymo Jul 27 '15 at 13:17

4 Answers4

4

To solve this problem i have followed these steps:

First i created a custom HorizontalScrollView class:

public class MyScrollView extends HorizontalScrollView{

    public MyScrollView(Context context) {
        super(context);

    }
    public MyScrollView(Context context, AttributeSet attrs) {
        super(context, attrs);

    }

    public MyScrollView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

    }

    @Override
    protected void onOverScrolled(int scrollX, int scrollY, boolean clampedX,boolean clampedY) {    

        Log.e(" horizontal ", " - "+scrollX);
            // here i call the listener i have created
        scrollViewListener.onHorizontalScrollChanged(scrollX, scrollY);

        super.onOverScrolled(0, scrollY, true, true);       
    }

    // i create a scroll view listener, and i instantiate this from main Activity
    private ScrollViewListener scrollViewListener = null;   
    public interface ScrollViewListener {
        void onHorizontalScrollChanged(int x, int y);
    }

    public void setScrollViewListener(ScrollViewListener scrollViewListener) {
        this.scrollViewListener = scrollViewListener;
    }

    @Override
    protected void onScrollChanged(int l, int t, int oldl, int oldt) {
        super.onScrollChanged(l, t, oldl, oldt);    
    }

}

In your MainActivity implement this:

implements MyScrollView.ScrollViewListener

@Override
public void onHorizontalScrollChanged(int x, int y) {
      // In your ViewPager call this method
      mPager.scrollBy(x, y);
}

Also in your MainActivity in onCreate you have to add this:

// i have also added this custom HorizontalScrollView to my XML
MyScrollView myScrollView = (MyScrollView) findViewById(R.id.h_scroll);
myScrollView.setScrollViewListener(this);

I implemented this code and it worked for me, i hope it works even for you :)

Ultimo_m
  • 4,724
  • 4
  • 38
  • 60
1

You need to create a custom ScrollView and override onInterceptTouchEvent and return false from it.

public class StoppableScrollView extends ScrollView {

  public StoppableScrollView(Context context) {
    super(context);
  }


  @Override
  public boolean onInterceptTouchEvent(MotionEvent ev) {
    return false;
  }

}

Sagar Waghmare
  • 4,702
  • 1
  • 19
  • 20
  • I've already tried that. It works but then items inside the HorizontalScrollView are not clickable. I need to intercept only the scroll event. – kmalmur Jun 05 '14 at 11:11
0

Is this what you need?

@Override
public boolean dispatchTouchEvent(MotionEvent ev){
   if(ev.getAction()==MotionEvent.ACTION_MOVE)
      return true;
   return super.dispatchTouchEvent(ev);
}
Michele La Ferla
  • 6,775
  • 11
  • 53
  • 79
  • it is not so easy, scroll event consists of Action_DOWN, Action_MOVE and Action_UP. Sometimes there is even different configuration for example when doubleclicked and scrolled right after the second click. – kmalmur Jun 04 '14 at 15:15
0

Try to set the DescendantFocusability of the viewpager.

 viewPager.setDescendantFocusability(ViewPager.FOCUS_BEFORE_DESCENDANTS);
Sripathi
  • 1,760
  • 15
  • 20