阻止RecyclerView手动滚动 [英] Prevent RecyclerView to scroll by hand

查看:286
本文介绍了阻止RecyclerView手动滚动的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个像专辑这样的项目的列表,并通过RecyclerView进行显示.

I have a list of items like an album and I show it by RecyclerView.

此外,每个项目都有一个按钮,可通过单击然后滚动到列表中的下一个位置来将一些数据发送到服务器.

Also, each item has a button to send some data to the server by clicking and then scroll to the next position in list.

所以我的问题是:

如何防止RecyclerView手动滚动(手势),但是如果调用smoothScrollToPosition()方法,则滚动到某个位置?

How to prevent RecyclerView from scrolling by hand (gesture) but scroll to a position if smoothScrollToPosition() method called?

推荐答案

这是水平滚动的解决方案,它允许您关闭滚动,但仍可以通过调用smoothScrollToPosition启用它.它还允许用户与回收者视图中的子视图进行交互.

Here's a solution for horizontal scrolling that allows you to turn off scrolling, but still enable it via calling smoothScrollToPosition. It also lets the user interact with child views within the recycler view.

我发现,其他使临时滚动能够调用smoothScrollToPosition的解决方案具有使用户中断滚动的副作用,即使禁用触摸事件或在recyclerview顶部添加另一个视图也是如此.

I found that the other solutions which enabled scrolling temporarily to be able to call smoothScrollToPosition had the side effect of letting the user interrupt scrolling, even when disabling touch events or adding another view on top of the recyclerview.

关键是要使smoothScrollToPosition正常工作是重写LinearSmoothScroller.calculateDxToMakeVisible并取消对canScrollHorizo​​ntally()的检查

The key is to getting smoothScrollToPosition to work is to override LinearSmoothScroller.calculateDxToMakeVisible and remove the check to canScrollHorizontally()

class NoScrollHorizontalLayoutManager(context: Context) : LinearLayoutManager(context, RecyclerView.HORIZONTAL, false) {

    override fun canScrollHorizontally(): Boolean {
        return false
    }

    override fun smoothScrollToPosition(recyclerView: RecyclerView, state: RecyclerView.State?, position: Int) {
        val linearSmoothScroller = ForceHorizontalLinearSmoothScroller(recyclerView.context)
        linearSmoothScroller.targetPosition = position
        startSmoothScroll(linearSmoothScroller)
    }
}



class ForceHorizontalLinearSmoothScroller(context: Context) : LinearSmoothScroller(context) {

    override fun calculateDxToMakeVisible(view: android.view.View, snapPreference: Int): Int {
        val layoutManager = layoutManager
        if (layoutManager == null) {
            return 0
        }
        val params = view.layoutParams as RecyclerView.LayoutParams
        val left = layoutManager.getDecoratedLeft(view) - params.leftMargin
        val right = layoutManager.getDecoratedRight(view) + params.rightMargin
        val start = layoutManager.paddingLeft
        val end = layoutManager.width - layoutManager.paddingRight
        return calculateDtToFit(left, right, start, end, snapPreference)
    }
}

我发现在滚动过程中点击回收视图时,用户仍然可以停止滚动.解决方法是覆盖 RecycleView.onInterceptTouchEvent 并防止在进行平滑滚动或将滚动状态设置为 SCROLL_STATE_SETTLING 时发生事件.(为此使用 RecycleView.addOnItemTouchListener 无效,因为RecycleView停止滚动,然后侦听器在 RecyleView.onInterceptTouchEvent 中返回true.)

I found that the user could still stop scrolling when tapping on the recycle view while the scroll was in progress. The fix was to override the RecycleView.onInterceptTouchEvent and prevent events when the smooth scroll was in progress or when the scroll state was set to SCROLL_STATE_SETTLING. (Using RecycleView.addOnItemTouchListener for this wont work because the RecycleView stops scrolling then the listener returns true in RecyleView.onInterceptTouchEvent.)

class NoScrollRecyclerView : 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 {
        if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) {
            return true
        }
        return super.onInterceptTouchEvent(e)
    }

    @SuppressLint("ClickableViewAccessibility")
    override fun onTouchEvent(e :MotionEvent) : Boolean {
        if (layoutManager?.isSmoothScrolling() == true || scrollState == SCROLL_STATE_SETTLING) {
            return true
        }
        return super.onTouchEvent(e)
    }
}

这篇关于阻止RecyclerView手动滚动的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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