如何通过编程方式禁用RecyclerView的滚动 [英] How to disable scrolling of RecyclerView except programmatically

查看:100
本文介绍了如何通过编程方式禁用RecyclerView的滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 RecyclerView ,其中 LinearLayoutManager 的方向为 HORIZONTAL .其中的每个项目都可以具有交互元素(包括垂直的 ScrollView s).有没有一种方法可以轻松地使 RecyclerView 忽略用户的任何尝试而水平滚动或弹出 RecyclerView 而不会拦截孩子的触摸事件?

I have a RecyclerView with a LinearLayoutManager in orientation HORIZONTAL. Each item in it can have interactive elements (including vertical ScrollViews). Is there a way to easily make the RecyclerView ignore any attempts by the user to scroll or fling the RecyclerView horizontally without intercepting touch events to the children?

我正在以编程方式控制 RecyclerView 的滚动,直到用户扔掉它之前,滚动条都很好用.

I am programmatically controlling the scroll of the RecyclerView which works great until the user flings it.

我尝试了一种非常简单的方法,即当我响应某些事件而调用smoothScrollToPosition时,启用滚动并禁用触摸事件,直到滚动稳定为止.像这样:

I have tried something very simple where the idea is when I call smoothScrollToPosition in response to some event, I enable scrolling and disable touch events until the scroll settles. Like this:

  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());

实际上几乎可以正常工作的

...但是当平滑滚动运动时,我仍然可以通过点击屏幕来固定程序化滚动.显然,我缺少明显的东西,或者有更聪明的方法来做到这一点.

which actually almost works... but I can still screw up the programmatic scroll by tapping the screen when the smooth scroll is in motion. clearly I'm missing something obvious or there is a much smarter way to do this.

UPDATE 非RecyclerView解决方案:

UPDATE the non-RecyclerView solution was found here: 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;
  }
}

推荐答案

覆盖onInterceptTouchEvent可以避免点击行为停止.

Overriding onInterceptTouchEvent you avoid the stop on click behaviour.

@Override
public boolean onInterceptTouchEvent(MotionEvent e) {
    return false;
}

这篇关于如何通过编程方式禁用RecyclerView的滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆