2015-09-27 24 views
19

我有RecyclerViewLinearLayoutManager方向HORIZONTAL。其中的每个项目都可以具有交互元素(包括垂直ScrollView s)。有没有一种方法可以轻松使RecyclerView忽略用户尝试水平滚动或滑动RecyclerView而不拦截对儿童的触摸事件?如何禁用滚动的RecyclerView除编程

我以编程方式控制RecyclerView的滚动,它的工作效果很好,直到用户滑过它。

我已经尝试了一些非常简单的想法,当我调用smoothScrollToPosition来响应某些事件时,我启用滚动并禁用触摸事件,直到滚动结算。就像这样:

private class NoScrollHorizontalLayoutManager extends LinearLayoutManager { 
    ScrollingTouchInterceptor interceptor = new ScrollingTouchInterceptor(); 
    protected boolean canScroll; 

    public NoScrollHorizontalLayoutManager(Context ctx) { 
     super(ctx, LinearLayoutManager.HORIZONTAL, false); 
    } 

    public RecyclerView.OnItemTouchListener getInterceptor() { 
     return interceptor; 
    } 

    @Override 
    public void smoothScrollToPosition(RecyclerView recyclerView, RecyclerView.State state, int position) { 
     canScroll = true; 
     super.smoothScrollToPosition(recyclerView, state, position); 
    } 

    @Override 
    public void onScrollStateChanged(int state) { 
     super.onScrollStateChanged(state); 
     if(state == RecyclerView.SCROLL_STATE_IDLE) { 
     canScroll = false; 
     } 
    } 

    @Override 
    public boolean canScrollHorizontally() { 
     return canScroll; 
    } 

    public class ScrollingTouchInterceptor implements RecyclerView.OnItemTouchListener { 
     @Override 
     public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent e) { 
     return canScrollHorizontally(); 
     } 

     @Override 
     public void onTouchEvent(RecyclerView rv, MotionEvent e) { 
     } 

     @Override 
     public void onRequestDisallowInterceptTouchEvent(boolean disallowIntercept) { 
     } 
    } 
    } 

而且使用这样的..

NoScrollHorizontalLayoutManager layout = new NoScrollHorizontalLayoutManager(context); 
recycler.setLayoutManager(layout); 
recycler.addOnItemTouchListener(layout.getInterceptor()); 

实际上几乎作品......但我仍然可以通过点击屏幕搞砸了编程滚动时平滑滚动正在运动。显然我错过了一些显而易见的事情,或者有一个更聪明的方法来做到这一点。

UPDATE非RecyclerView溶液这里找到: How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

/** 
* ViewPager that doesn't allow swiping. 
*/ 
public class NonSwipeableViewPager extends ViewPager { 

    public NonSwipeableViewPager(Context context) { 
    super(context); 
    } 

    public NonSwipeableViewPager(Context context, AttributeSet attrs) { 
    super(context, attrs); 
    } 

    @Override 
    public boolean onInterceptTouchEvent(MotionEvent event) { 
    // Never allow swiping to switch between pages 
    return false; 
    } 

    @Override 
    public boolean onTouchEvent(MotionEvent event) { 
    // Never allow swiping to switch between pages 
    return false; 
    } 
} 
+0

我结束了刚刚使用旧式的ViewPager ...,完美的工作与更少的代码...哦,好吧。 – danb

+0

没有明白你想要做什么。 –

+0

发布代码,您如何处理它 –

回答

0
android:nestedScrollingEnabled="false" 

不要在XML文件中的上述之一,在RecyclerView TAG。

+0

这个不会做任何事,不幸的是 – danb

+0

这里同样没有效果。请任何其他想法? – Karoly

+0

android:nestedScrollingEnabled =“false”这个函数用于如果你想使用scrollview而不是recyclerview滚动.. – ZeroOne

0

首先,我不认为这是可以非编程方式实现的。

方式1:简单 - 基于触摸禁用其他视图。

如果用户触摸父级,则禁用子视图滚动。反之亦然,以及代码

件要做到这一点

recyclerView.setOnTouchListener(new View.OnTouchListener() 
{ 
    public boolean onTouch(View p_v, MotionEvent p_event) 
    { 
     yourChildView.getParent().requestDisallowInterceptTouchEvent(false); 
     return false; 
    } 
}); 

方式二:既然你是在你的执行的小问题。如果你发布它,有人可以修复它。

+0

我想你误会了。问题是我不希望用户能够滑动回收站视图。我只是想让它在代码中告诉它时才会移动。所有的孩子的意见应该正常行事(他们这样做) – danb

+0

是的可能。望着它。你可以尝试更多的东西吗? 设置'viewpager'的触摸监听器并始终返回true –

+0

我在答案中添加的viewpager解决方案按预期工作。现在正在投入生产 – danb

0

重写onInterceptTouchEvent可以避免停止点击行为。

@Override 
public boolean onInterceptTouchEvent(MotionEvent e) { 
    return false; 
} 
0
recyclerView.setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) { 
      return true; 
     } 
    }); 
+0

尽管如此,这还可以禁止在查看持有者的任何触摸事件。 –

0
recyclerView.setNestedScrollingEnabled(false); 

欲了解更多信息请参阅documentation

0

这给出了连续性的效果。

recyclerView.setOnTouchListener(new View.OnTouchListener() { 
      @Override 
      public boolean onTouch(View v, MotionEvent event) { 
       int action = event.getAction(); 
       if (action == MotionEvent.ACTION_DOWN) { 
        recyclerView.smoothScrollToPosition(position); 
        return true; 
       } else if (action == MotionEvent.ACTION_UP) { 
        recyclerView.smoothScrollToPosition(position); 
        return true; 
       } 
       return false; 
      } 
     });