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
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
}
}
}
<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
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
}
}
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);
}
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
.