How to disable overscroll effect on RecyclerView ONLY when you can't scroll anyway ?

前端 未结 5 1028
囚心锁ツ
囚心锁ツ 2021-02-07 00:38

Background

Sometimes, all items of the recyclerView are already visible to the user.

In this case, it wouldn\'t matter to the user to see overscroll effect, be

相关标签:
5条回答
  • 2021-02-07 01:08

    Longer workaround, based on here (to solve this issue), handles more cases, but still a workaround:

    /**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
            }
        }
    }
    
    0 讨论(0)
  • 2021-02-07 01:17
    <android.support.v7.widget.RecyclerView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:overScrollMode="never"/>
    

    Just add android:overScrollMode="never" in XML

    0 讨论(0)
  • 2021-02-07 01:20

    Since android:overScrollMode="ifContentScrolls" is not working for RecyclerView(see https://issuetracker.google.com/issues/37076456) I found some kind of a workaround which want to share with you:

    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
        }
    }
    
    0 讨论(0)
  • 2021-02-07 01:24

    you could give OVER_SCROLL_IF_CONTENT_SCROLLS a try. Accordingly to the documentation

    Allow a user to over-scroll this view only if the content is large enough to meaningfully scroll, provided it is a view that can scroll.

    Or you could check if you have enough items to trigger the scroll and enable/disable the over scroll mode, depending on it. Eg

    boolean notAllVisible = layoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 1;
    if (notAllVisible) {
       recyclerView.setOverScrollMode(allVisible ? View.OVER_SCROLL_NEVER);
    }
    
    0 讨论(0)
  • 2021-02-07 01:28

    You could try something like this:

    totalItemCount = linearLayoutManager.getItemCount();
    firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
    lastVisibleItem = linearLayoutManager.findLastCompletelyVisibleItemPosition();
    
    if(firstVisibleItem == 0 && lastVisibleItem -1 == totalItemCount){
        // trigger the overscroll effect
    }
    

    Which you could add in the onScrolled() of an OnScrollListener that you add on your RecyclerView.

    0 讨论(0)
提交回复
热议问题