HorizontalScrollView inside ScrollView - disable vertical scroll when horizontal scroll is in progress

Lucas picture Lucas · Mar 24, 2014 · Viewed 8.6k times · Source

I have a parent which is ScrollView, which holds a HorizontalScrollView as one of it's child views. All works perfectly, but when someone is triggering vertical scroll, the horizontal scroll stops, or is jittering. On top of it, there is some bug in Ice Cream Sandwich which does not handle vertical movement on HorizontalScrollView well, if it is inside a ScrollView, which content is smaller than the screen (in that situation, there is no vertical scrolling). Jelly Bean android handles it properly, but IceCreamSandwich for some reason detects the vertical movement, and stops the horizontal scrolling.

How would I go about making the parent scrollView disable it's vertical scroll, when a horizontal scroll is being triggered? So when someone is scrolling horizontally the HorizontalScrollView, and while doing it, the finger wonders a bit on a Y Axis, I do not want the parent ScrollView to capture that vertical motion.

Any help with that?

Answer

Hardik picture Hardik · Mar 24, 2014

just try this

HorizontalScrollView hv = (HorizontalScrollView)findViewById(R.id.myHsView);  // your HorizontalScrollView inside scrollview
    hv.setOnTouchListener(new ListView.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                int action = event.getAction();
                switch (action) {
                case MotionEvent.ACTION_DOWN:
                    // Disallow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(true);
                    break;

                case MotionEvent.ACTION_UP:
                    // Allow ScrollView to intercept touch events.
                    v.getParent().requestDisallowInterceptTouchEvent(false);
                    break;
                }

                // Handle HorizontalScrollView touch events.
                v.onTouchEvent(event);
                return true;
            }
        });