horizontalscrollview inside viewpager

2019-05-22 17:02发布

问题:

I have a viewpager with 2 to 4 pages. One of these pages presentes data in table form. To do so i use a vertical scroll and a horizontal scroll.

Due to conflicts between horizontalscrollview and viewpager, sometimes, scrolling does nothing.

I want to scroll the page while it has scroll left. When it reaches the edge, another swipe gesture will make it change the page of view pager, following guideline from http://developer.android.com/design/patterns/swipe-views.html where it states: "If a view contains content that exceeds the width of the screen such as a wide email message, make sure the user's initial swipes will scroll horizontally within the view. Once the end of the content is reached, an additional swipe should navigate to the next view. In addition, support the use of edge swipes to immediately navigate between views when content scrolls horizontally."

How can i achieve this?

回答1:

In the end I made a custom pager and overrided the method canScroll like so

@Override
protected boolean canScroll(View v, boolean checkV, int dx, int x, int y) {
    if (v instanceof HorizontalScrollView) {
        HorizontalScrollView scroll = (HorizontalScrollView) v;

        int vScrollX = scroll.getScrollX();
        TableLayout table = (TableLayout) scroll.getChildAt(scroll
                .getChildCount() - 1);
        int diff = (table.getRight() - (scroll.getWidth()
                + scroll.getScrollX() + table.getLeft()));

        if (vScrollX == 0 && diff <= 0) {// table without scroll
            if (dx > 20 && this.getCurrentItem() > 0) {
                this.setCurrentItem(this.getCurrentItem() - 1, true);
            } else if (dx < -20
                    && this.getCurrentItem() + 1 < this.getChildCount()) {
                this.setCurrentItem(this.getCurrentItem() + 1, true);
            }
            return false; // change page
        }
        if (vScrollX == 0 && dx > 20) {// left edge, swiping right
            if (this.getCurrentItem() > 0) {
                this.setCurrentItem(this.getCurrentItem() - 1, true);
            }
            return false; // change page
        }
        if (vScrollX == 0 && dx < -20) {// left edge, swiping left
            return true;// scroll
        }
        if (diff <= 0 && dx > 20) {// right edge, swiping right
            return true;// scroll
        }
        if (diff <= 0 && dx < -20) {// right edge, swiping left
            if (this.getCurrentItem() + 1 < this.getChildCount()) {
                this.setCurrentItem(this.getCurrentItem() + 1, true);
            }
            return false;// change page
        }
    }
    return super.canScroll(v, checkV, dx, x, y);
}