无论如何都无法滚动时,如何仅在 RecyclerView 上禁用过度滚动效果?
How to disable overscroll effect on RecyclerView ONLY when you can't scroll anyway ?
背景
有时,recyclerView 的所有项目都已经对用户可见。
在这种情况下,用户看到过度滚动效果并不重要,因为不可能真正滚动并看到更多项目。
问题
我知道为了禁用 RecyclerView 的过度滚动效果,我可以使用:
recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
但我不知道什么时候触发它,无论如何都无法滚动。
问题
我如何确定所有项目都完全可见并且用户不能真正滚动?
如果假设有任何帮助,我总是为 RecyclerView 使用 LinearLayoutManager(垂直和水平)。
你可以 OVER_SCROLL_IF_CONTENT_SCROLLS
试一试。根据文档
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.
或者您可以检查是否有足够的项目来触发滚动和 enable/disable 过度滚动模式,具体取决于它。例如
boolean notAllVisible = layoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 1;
if (notAllVisible) {
recyclerView.setOverScrollMode(allVisible ? View.OVER_SCROLL_NEVER);
}
您可以尝试这样的操作:
totalItemCount = linearLayoutManager.getItemCount();
firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
lastVisibleItem = linearLayoutManager.findLastCompletelyVisibleItemPosition();
if(firstVisibleItem == 0 && lastVisibleItem -1 == totalItemCount){
// trigger the overscroll effect
}
您可以在 OnScrollListener
的 onScrolled()
中添加您在 RecyclerView
中添加的内容。
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"/>
只需在XML
中添加android:overScrollMode="never"
由于 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
}
}
更长的解决方法,基于 (to solve 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
}
}
}
背景
有时,recyclerView 的所有项目都已经对用户可见。
在这种情况下,用户看到过度滚动效果并不重要,因为不可能真正滚动并看到更多项目。
问题
我知道为了禁用 RecyclerView 的过度滚动效果,我可以使用:
recyclerView.setOverScrollMode(View.OVER_SCROLL_NEVER);
但我不知道什么时候触发它,无论如何都无法滚动。
问题
我如何确定所有项目都完全可见并且用户不能真正滚动?
如果假设有任何帮助,我总是为 RecyclerView 使用 LinearLayoutManager(垂直和水平)。
你可以 OVER_SCROLL_IF_CONTENT_SCROLLS
试一试。根据文档
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.
或者您可以检查是否有足够的项目来触发滚动和 enable/disable 过度滚动模式,具体取决于它。例如
boolean notAllVisible = layoutManager.findLastCompletelyVisibleItemPosition() < adapter.getItemCount() - 1;
if (notAllVisible) {
recyclerView.setOverScrollMode(allVisible ? View.OVER_SCROLL_NEVER);
}
您可以尝试这样的操作:
totalItemCount = linearLayoutManager.getItemCount();
firstVisibleItem = linearLayoutManager.findFirstCompletelyVisibleItemPosition()
lastVisibleItem = linearLayoutManager.findLastCompletelyVisibleItemPosition();
if(firstVisibleItem == 0 && lastVisibleItem -1 == totalItemCount){
// trigger the overscroll effect
}
您可以在 OnScrollListener
的 onScrolled()
中添加您在 RecyclerView
中添加的内容。
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:overScrollMode="never"/>
只需在XML
中添加android:overScrollMode="never"
由于 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
}
}
更长的解决方法,基于
/**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
}
}
}