在Fragment中使用Horizo​​ntalScrollView的垂直ViewPager

时间:2017-10-19 11:32:29

标签: android android-viewpager horizontalscrollview touch-event

我有一个VerticalViewPager,其Fragment内容我想横向滚动。垂直分页工作正常,直到水平内容足够大才能滚动。之后,触摸事件不会传递到ViewPager,因此分页不再有效。

MVCE

这可以通过设置我刚发布的this answer中给出的简单项目来重现。

替换fragment_one.xml文件
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                android:layout_width="match_parent"
                android:layout_height="match_parent" >

    <HorizontalScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_centerInParent="true" >

        <TextView
            android:id="@+id/textview"
            android:textSize="30sp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />

    </HorizontalScrollView>

</RelativeLayout>

并将文本设置为任意长度以便水平滚动。

我尝试过的事情

1 个答案:

答案 0 :(得分:0)

为了回答这个问题和其他类似问题,了解Android框架如何处理触摸事件非常有帮助。我的fuller answer on that is here,但我会在下面添加摘要图。

enter image description here

HorizontalScrollView(图中的ViewGroup B)在VerticalViewPager(ViewGroup A)有机会之前处理所有触摸事件。因此,解决方案是在onInterceptTouchEvent()中使用VerticalViewPager来有选择地过滤掉垂直滚动。为此,最简单的方法是使用GestureDetector.SimpleOnGestureListener.onScroll()

以下是您需要对VerticalViewPager类进行的相关更改:

public class VerticalViewPager extends ViewPager {

    GestureDetector mDetector;

    private void init() {
        // ...
        mDetector = new GestureDetector(getContext(), new VerticalScrollListener());
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {
        super.onInterceptTouchEvent(flipXY(ev));
        flipXY(ev);

        return mDetector.onTouchEvent(ev);
    }

    class VerticalScrollListener extends GestureDetector.SimpleOnGestureListener {
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, 
                                float distanceX, float distanceY) {
            return Math.abs(distanceY) > Math.abs(distanceX);
        }
    }
}