ScrollView Inside ScrollView

Try this one

Note: Here parentScrollView means Outer ScrollView And childScrollView means Innner ScrollView

parentScrollView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
        Log.v(TAG, "PARENT TOUCH");

        findViewById(R.id.child_scroll).getParent()
                .requestDisallowInterceptTouchEvent(false);
        return false;
    }
});

childScrollView.setOnTouchListener(new View.OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
        Log.v(TAG, "CHILD TOUCH");

        // Disallow the touch request for parent scroll on touch of  child view
        v.getParent().requestDisallowInterceptTouchEvent(true);
        return false;
    }
});

Is this close enough?

You should never use a HorizontalScrollView with a ListView, since ListView takes care of its own scrolling. Most importantly, doing this defeats all of the important optimizations in ListView for dealing with large lists, since it effectively forces the ListView to display its entire list of items to fill up the infinite container supplied by HorizontalScrollView.

http://developer.android.com/reference/android/widget/HorizontalScrollView.html

UPDATE:

Since you may be forced to use a two dimensional scrollview, you may consider using this: Internet archive of blog.gorges.us/2010/06/android-two-dimensional-scrollview/

I haven't used this but it may be a reasonable approach.


Atul Bhardwaj's answer above is the correct way to do it. But in case someone needs to apply it to a ScrollView where you have less control of the parent, I think this is flexible enough and just the way it's supposed to work:

private void makeMyScrollSmart() {
    myScroll.setOnTouchListener(new View.OnTouchListener() {
        @Override
        public boolean onTouch(View __v, MotionEvent __event) {
            if (__event.getAction() == MotionEvent.ACTION_DOWN) {
                //  Disallow the touch request for parent scroll on touch of child view
                requestDisallowParentInterceptTouchEvent(__v, true);
            } else if (__event.getAction() == MotionEvent.ACTION_UP || __event.getAction() == MotionEvent.ACTION_CANCEL) {
                // Re-allows parent events
                requestDisallowParentInterceptTouchEvent(__v, false);
            }
            return false;
        }
    });
}

private void requestDisallowParentInterceptTouchEvent(View __v, Boolean __disallowIntercept) {
    while (__v.getParent() != null && __v.getParent() instanceof View) {
        if (__v.getParent() instanceof ScrollView) {
            __v.getParent().requestDisallowInterceptTouchEvent(__disallowIntercept);
        }
        __v = (View) __v.getParent();
    }
}

What the function does is add a touch listener to myScroll that disables the parent's touch intercept when a touch starts in the child, and then enables it back when the touch actually ends. You don't need a reference to the parent ScrollView and it doesn't have to be the immediate parent... it'll travel the display list until it finds it.

Best of both worlds, in my opinion.