如果无法滚动,如何仅在RecyclerView上禁用过度滚动效果?

时间:2016-12-29 14:27:13

标签: android android-recyclerview overscroll

背景

有时,RecyclerView的所有项目都已为用户所见。

在这种情况下,用户看到过度滚动效果并不重要,因为实际滚动并看到更多项目是不可能的。

问题

我知道为了在RecyclerView上禁用过度滚动效果,我可以使用:

recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);

但我无法找到何时触发此功能,无论如何都无法滚动。

问题

如何确定所有项目完全可见并且用户无法真正滚动?

如果它有所帮助,我总是使用LinearLayoutManager(垂直和水平)作为RecyclerView。

5 个答案:

答案 0 :(得分:10)

你可以试试OVER_SCROLL_IF_CONTENT_SCROLLS。根据文件

  

仅当内容很大时,允许用户过度滚动此视图   足以有意义地滚动,只要它是一个可以滚动的视图。

或者您可以检查是否有足够的项目来触发滚动并启用/禁用过滚动模式,具体取决于它。例如

boolean notAllVisible = layoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 1;
if (notAllVisible) {
   recyclerView.setOverScrollMode(allVisible ? View.OVER_SCROLL_NEVER);
}

答案 1 :(得分:5)

<android.support.v7.widget.RecyclerView
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:overScrollMode="never"/>

只需在XML中添加android:overScrollMode="never"

即可

答案 2 :(得分:2)

由于android:overScrollMode="ifContentScrolls"RecyclerView不起作用(请参阅https://issuetracker.google.com/issues/37076456),我发现了一种可以与您分享的解决方法:

class MyRecyclerView @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0
) : RecyclerView(context, attrs, defStyleAttr) {

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        val canScrollVertical = computeVerticalScrollRange() > height
        overScrollMode = if (canScrollVertical) OVER_SCROLL_ALWAYS else OVER_SCROLL_NEVER
    }
}

答案 3 :(得分:1)

您可以尝试这样的事情:

totalItemCount = linearLayoutManager.getItemCount();
firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
lastVisibleItem = linearLayoutManager.findLastCompletelyVisibleItemPosition();

if(firstVisibleItem == 0 && lastVisibleItem -1 == totalItemCount){
    // trigger the overscroll effect
}

您可以在onScrolled()添加的OnScrollListener RecyclerView中添加。

答案 4 :(得分:0)

基于here(用于解决this issue)的更长的解决方法可以处理更多情况,但仍然是一种解决方法:

/**a temporary workaround to make RecyclerView handle android:overScrollMode="ifContentScrolls"  */
class NoOverScrollWhenNotNeededRecyclerView : RecyclerView {
    private var enableOverflowModeOverriding: Boolean? = null
    private var isOverFlowModeChangingAccordingToSize = false

    constructor(context: Context) : super(context)
    constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
    constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr)

    override fun setOverScrollMode(overScrollMode: Int) {
        if (!isOverFlowModeChangingAccordingToSize)
            enableOverflowModeOverriding = overScrollMode == View.OVER_SCROLL_IF_CONTENT_SCROLLS
        else isOverFlowModeChangingAccordingToSize = false
        super.setOverScrollMode(overScrollMode)
    }

    override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
        super.onLayout(changed, l, t, r, b)
        if (enableOverflowModeOverriding == null)
            enableOverflowModeOverriding = overScrollMode == View.OVER_SCROLL_IF_CONTENT_SCROLLS
        if (enableOverflowModeOverriding == true) {
            val canScrollVertical = computeVerticalScrollRange() > height
            val canScrollHorizontally = computeHorizontalScrollRange() > width
            isOverFlowModeChangingAccordingToSize = true
            overScrollMode = if (canScrollVertical || canScrollHorizontally) OVER_SCROLL_ALWAYS else OVER_SCROLL_NEVER
        }
    }
}