【问题标题】:Restrict user scrolling in RecyclerView限制用户在 RecyclerView 中滚动
【发布时间】:2019-01-27 02:27:18
【问题描述】:

在我的项目中,我使用了一个我只想通过调用 LayoutManager 的 startSmoothScroll() 方法来滚动的 RecyclerView:

private fun next(){
    val layoutManager = pager.layoutManager as BattlePageLayoutManager
    layoutManager.startSmoothScroll(smoothScroller(layoutManager.findFirstVisibleItemPosition() + 1))
    layoutManager.finishScroll()
}

我不希望用户能够手动滚动,例如。 G。通过刷卡。

我已经尝试通过覆盖父 FrameLayout 的 onInterceptTouchEvent() 方法来实现这一点。

    override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
        if (ev.actionMasked == MotionEvent.ACTION_DOWN){
            startClickTime = System.currentTimeMillis()
            startX = ev.x
            startY = ev.y
        }        
        val allowEvent = (System.currentTimeMillis() - startClickTime) < 1000 && (startX-ev.x).absoluteValue < 15 && (startY-ev.y).absoluteValue < 15
        return !allowEvent
    }

这基本上是有效的,但是在双击视图后,用户可以自己滚动。

您还有其他想法可以解决这个问题吗?

【问题讨论】:

  • 是ViewPager 还是RecyclerView 想要阻止滚动?我看到您要求RecyclerView,但我也看到您的layoutManager 来自pager。
  • 它是一个 RecyclerView,但它的工作方式类似于 ViewPager。我这样做是因为我想使用 Android Paging Library。有没有使用 ViewPager 实现这些行为的简单方法?

标签: android android-layout kotlin android-recyclerview


【解决方案1】:

您是否尝试在 LayoutManager 中覆盖 canScrollVertically() 方法?

mLayoutManager = new LinearLayoutManager(getActivity()) {
    @Override
    public boolean canScrollVertically() {
        return false;
    }
};

编辑: 创建您自己的 RecyclerView 实现,它会在滚动执行时禁用触摸事件。然后你必须改变 xml 文件中的 RecyclerView 类和 Fragment/Activity 。

在这里找到一个 Kotlin 示例

class MyRecyclerView : RecyclerView {
    constructor(context: Context) : super(context) {}

    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {}

    constructor(context: Context, attrs: AttributeSet?, defStyle: Int) : super(context, attrs, defStyle) {}

    override fun onInterceptTouchEvent(e: MotionEvent): Boolean {
        return if (scrollState != RecyclerView.SCROLL_STATE_IDLE) false else super.onInterceptTouchEvent(e)
    }
}

在 Java 中

public class MyRecyclerView extends RecyclerView {
    public MyRecyclerView(Context context) {
        super(context);
    }

    public MyRecyclerView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public MyRecyclerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public boolean onInterceptTouchEvent(MotionEvent e) {
        if(getScrollState() != SCROLL_STATE_IDLE)
            return false;
        return super.onInterceptTouchEvent(e);
    }
}

【讨论】:

  • 是的,但是 smartSmoothScrolling 方法也不能这样使用。
  • 创建您自己的 RecyclerView 实现,它在滚动执行时禁用触摸事件。检查编辑!
  • 很遗憾,scrollState 始终为 0
  • mmm...我尝试过并且为我工作...但我打电话给recyclerView.startSmoothScroll(...)而不是layoutManager.startSmoothScroll()。稍后我将尝试对 layoutManager 执行相同的操作。也许在onInterceptTouchEvent 方法中你可以检查getLayoutManager().isSmoothScrolling() 然后禁用手势
  • 我发现,'onInterceptTouchEvent' 中的状态总是 0,但在 'dispatchTouchEvent' 中却不是。基于此,我找到了解决方案。
【解决方案2】:

您可能希望阻止用户与 RecyclerView 的交互,而不是与 FrameLayout 本身的交互。

检查RecyclerView.OnItemTouchListener。

在您的RecyclerView 中,您可以实现OnItemTouchListener 并覆盖所有方法以不执行任何操作。

这将阻止用户与RecyclerView 的交互,使滚动不会发生。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-30
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2018-05-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多