0

我的应用程序当前由ViewPager组成,其中有几个Fragments。在一个特定的Fragment我有一个SwipeRefreshLayoutScrollView和这个容器,一个Horizo​​talListView类型TwoWayView在水平列表视图中滑动时禁用垂直刷卡(SwipeRefreshLayout)

问题是当我在ListView中水平滑动时,SwipeRefreshLayout的垂直滚动未被禁用,有时它在操作过程中中断了水平滑动。

这就是我试图做来解决它:

horizListView.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. 
       mSwipeRefreshLayout.requestDisallowInterceptTouchEvent(true); 
       v.getParent().requestDisallowInterceptTouchEvent(true); 
       break; 
      case MotionEvent.ACTION_UP: 
       // Allow ScrollView to intercept touch events. 
       mSwipeRefreshLayout.requestDisallowInterceptTouchEvent(false); 
       v.getParent().requestDisallowInterceptTouchEvent(false); 
       break; 
     } 

     // Handle HorizontalScrollView touch events. 
     v.onTouchEvent(event); 
     return 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> 

如果有人可以帮助我,这将是巨大的。

+0

尝试删除'v.onTouchEvent(事件);'并返回false,而不是真正的 – 2014-10-06 14:23:36

+0

我只是尝试它,但它不工作 – 2014-10-06 14:31:36

+0

你应该做一个自定义的swiperefreshlayout,试试这个,[点击这里]( http://stackoverflow.com/questions/23989910/horizo​​ntalscrollview-inside-swiperefreshlayout) – 2016-02-23 06:49:12

回答

0

重写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); 
} 
} 
0

我曾与SwipeRefreshLayout拦截触摸事件类似的问题。在最新的支持库中(我使用的是25.3.1 atm),这可以在不扩展SwipeRefreshLayout的情况下处理。以下是我做的:应该接收触摸事件必须回报在isNestedScrollingEnabled()真正

  1. 你的看法。
  2. 对于ACTION_DOWN事件,您的触摸监听器必须onTouchEvent()中返回true。否则,该指针标识的事件将由SwipeRefreshLayout处理。
  3. 您的触摸监听器必须对于您想要处理视图的所有操作在onTouchEvent()中返回true。
  4. 使用requestDisallowInterceptTouchEvent(bool)关闭/开启SwipeRefreshLayout及其父项(如果有)的触敏性。

在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; 
} 
} 
相关问题