首页 > 解决方案 > 限制用户在 RecyclerView 中滚动

问题描述

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

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

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

我已经尝试通过覆盖父 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
    }

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

你有其他想法来解决这个问题吗?

标签: androidandroid-layoutkotlinandroid-recyclerview

解决方案


您是否尝试在 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);
    }
}

推荐阅读