Android 在水平列表视图中滑动时禁用垂直滑动(SwipeRefreshLayout)

Android 在水平列表视图中滑动时禁用垂直滑动(SwipeRefreshLayout),android,android-viewpager,swipe,horizontalscrollview,swiperefreshlayout,Android,Android Viewpager,Swipe,Horizontalscrollview,Swiperefreshlayout,我的应用程序目前由一个ViewPager组成,它有几个片段。在一个特定的片段中,我有一个swiperFreshLayout和一个滚动视图,在这个容器中,有一个双向视图类型的水平视图 问题是当我在列表视图中水平滑动时,SwipeRefreshLayout的垂直滚动未被禁用,有时在操作过程中会中断水平滑动 这就是我试图解决的问题: horizListView.setOnTouchListener(新的ListView.OnTouchListener(){ @凌驾 公共布尔onTouch(视图v,运动

我的应用程序目前由一个
ViewPager
组成,它有几个
片段
。在一个特定的
片段
中,我有一个
swiperFreshLayout
和一个
滚动视图
,在这个容器中,有一个
双向视图
类型的水平视图

问题是当我在
列表视图中水平滑动时,
SwipeRefreshLayout
的垂直滚动未被禁用,有时在操作过程中会中断水平滑动

这就是我试图解决的问题:

horizListView.setOnTouchListener(新的ListView.OnTouchListener(){
@凌驾
公共布尔onTouch(视图v,运动事件){
int action=event.getAction();
开关(动作){
case MotionEvent.ACTION\u DOWN:
//不允许ScrollView截取触摸事件。
mSwipeRefreshLayout.RequestDisallowWinterCeptTouchEvent(true);
v、 getParent().RequestDisallowWinterCeptTouchEvent(true);
打破
case MotionEvent.ACTION\u UP:
//允许ScrollView截取触摸事件。
mSwipeRefreshLayout.RequestDisallowWinterCeptTouchEvent(false);
v、 getParent().RequestDisallowWinterCeptTouchEvent(false);
打破
}
//处理水平滚动查看触摸事件。
v、 事件;
返回true;
}
});
这是我的布局:

<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/container"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <ScrollView
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
            <LinearLayout
                android:layout_width="match_parent"
                android:orientation="vertical"
                android:layout_height="match_parent">

                <TextView
                    android:id="@+id/tv_info1"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:padding="10dp"
                    android:textStyle="bold"
                    android:textSize="@dimen/text_medium"
                    android:textColor="@color/light_gray"
                    android:text="@string/place_proposal" />

                <org.lucasr.twowayview.TwoWayView
                    android:orientation="horizontal"
                    android:id="@+id/horizlistview"
                    android:layout_height="230dp"
                    android:scaleType="centerCrop"
                    android:drawSelectorOnTop="false"
                    android:layout_width="fill_parent" />

                <TextView
                    android:id="@+id/tv_info2"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:textColor="@color/light_gray"
                    android:textSize="@dimen/text_medium"
                    android:textStyle="bold"
                    android:padding="10dp"
                    android:text="@string/actual_position"
                    android:paddingTop="5dp" />

                <ViewFlipper xmlns:android="http://schemas.android.com/apk/res/android"
                    android:id="@+id/vf"
                    android:layout_width="fill_parent"
                    android:layout_height="wrap_content">

                    <include
                        android:id="@+id/include_w"
                        layout="@layout/include_wicard_homescreen" />

                    <include
                        android:id="@+id/include_no_w"
                        layout="@layout/include_no_wicard" />

                </ViewFlipper>

            </LinearLayout>
    </ScrollView>

</android.support.v4.widget.SwipeRefreshLayout>


如果有人能帮我的话,那就太好了。

。这是我的代码,它运行良好:

public class RefreshLayoutExIntercepter extends SwipeRefreshLayout {

public RefreshLayoutExIntercepter(Context ctx) {
    super(ctx);
    mTouchSlop = ViewConfiguration.get(ctx).getScaledTouchSlop();
}

public RefreshLayoutExIntercepter(Context ctx, AttributeSet attrs) {
    super(ctx, attrs);
    mTouchSlop = ViewConfiguration.get(ctx).getScaledTouchSlop();
}

private int mTouchSlop;
private float mPrevX;

@Override
public boolean onInterceptTouchEvent(MotionEvent event) {

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN:
        mPrevX = event.getX();
        break;

    case MotionEvent.ACTION_MOVE:
        final float eventX = event.getX();
        float xDiff = Math.abs(eventX - mPrevX);

        if (xDiff > mTouchSlop) {
            return false;
        }
    }

    return super.onInterceptTouchEvent(event);
}
}

我在拦截触摸事件时也遇到了类似的问题。在最新的支持库中(我使用的是25.3.1 atm),这可以在不扩展布局的情况下处理。我是这样做的:

  • 应该接收触摸事件的视图必须在
    isNestedScrollingEnabled()中返回true
  • 您的touch listener必须在
    onTouchEvent()
    中返回true,以执行动作关闭事件。否则,具有此指针id的事件将由SwipeRefreshLayout处理
  • 对于要使用视图处理的所有操作,触摸监听器必须在
    onTouchEvent()
    中返回true
  • 使用
    requestDisallowWinterCeptTouchEvent(bool)
    关闭/打开SwiperFreshLayout及其父级(如果有)的触摸感应
  • 在OP的案例中,设置<代码>RecyclerView.setNestedScrollingEnabled(true)应该可以解决这个问题

    下面是我的自定义视图代码示例。使用此视图时,我可以通过水平滑动来更改选项卡,并在视图一直向上滚动时享受SwipeRefreshLayout的功能。此视图使用所有其他垂直滚动。我希望有帮助

    public void CustomScrollableView extends View {
    private final GestureDetector.SimpleOnGestureListener mGestureListener = new GestureDetector.SimpleOnGestureListener() {
    
        @Override
        public boolean onDown(MotionEvent e) {
            return true;
        }
    
        @Override
        public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
            // Check if view is zoomed.
            if (mIsZooming)
                return true;
    
            if (Math.abs(distanceY) < Math.abs(distanceX)) return false; // horizontal scrolling
    
            // Calculate the new origin after scroll.
            mYOffset -= distanceY;
            ViewCompat.postInvalidateOnAnimation(CustomScrollableView.this);
            return mYOffset < 0;
        }
    }
    
    private void blockParentScrolling(final boolean block) {
        final ViewParent parent = getParent();
        if (parent != null) {
            parent.requestDisallowInterceptTouchEvent(block);
        }
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        boolean consumedByGestureDetector = mGestureDetector.onTouchEvent(event);
        blockParentScrolling(consumedByGestureDetector);
        return consumedByGestureDetector;
    }
    
    @Override
    public boolean isNestedScrollingEnabled() {
        return true;
    }
    }
    
    public void CustomScrollableView扩展了视图{
    private final GestureDetector.SimpleOnGestureListener mGestureListener=新建GestureDetector.SimpleOnGestureListener(){
    @凌驾
    公共布尔onDown(运动事件e){
    返回true;
    }
    @凌驾
    公共布尔onScroll(MotionEvent e1、MotionEvent e2、浮点距离X、浮点距离Y){
    //检查视图是否已缩放。
    如果(变焦)
    返回true;
    if(Math.abs(distanceY)
    尝试删除
    v.ontochevent(事件)
    并返回false而不是True我刚刚尝试了它,但它不起作用您应该创建一个自定义swiperefreshlayout,试试这个,