如何解决RecyclerView.LinearLayout 管理器 findLastCompletelyVisibleItemPosition() 返回 PagedListAdapter 中的不可见位置
我的目标是向用户展示已显示的项目。在 findLastCompletelyVisibleItemPosition()
中使用 RecyclerView.addOnScrollListener(listener)
时,侦听器会被调用两次。
第一次调用 onScrolled()
时,我得到了不可见的位置,例如:
如果我有 10 个项目,而屏幕上只显示 5 个,findLastCompletelyVisibleItemPosition()
将返回位置 0-8。
第二次调用 onScrolled()
时,我得到了预期的位置 0-4。
我似乎无法找到这种行为的原因(在这里查看了多个帖子,可能的原因可能导致这种行为,但不适用于我的用例和/或实现)。
尝试更改 RecyclerView 高度/宽度以匹配父级 - 没有帮助。
发布我认为相关的代码部分。如果您需要其他部件或不清楚的地方 - 随时询问。
这是代码:
自定义父适配器:
abstract class CustomPagedListAdapter<T,VH : RecyclerView.ViewHolder> : PagedListAdapter<T,VH> {
constructor(callback: DiffUtil.ItemCallback<T>,visibleItemsListener: ((T) -> Unit)? = null) : super(callback) {
this.visibleItemsListener = visibleItemsListener
}
constructor(config: AsyncDifferConfig<T>,visibleItemsListener: ((T) -> Unit)? = null) : super(config) {
this.visibleItemsListener = visibleItemsListener
}
private val visibleItemsListener: ((T) -> Unit)?
private val itemsShown = hashMapOf<T,Boolean>()
override fun onAttachedToRecyclerView(recyclerView: RecyclerView) {
super.onAttachedToRecyclerView(recyclerView)
recyclerView.layoutManager?.let {
when (it) {
is LinearLayoutManager -> {
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView,dx: Int,dy: Int) {
val firstPosition = it.findFirstCompletelyVisibleItemPosition()
val lastPosition = it.findLastCompletelyVisibleItemPosition()
dispatchVisibleItems(firstPosition,lastPosition)
}
})
}
is GridLayoutManager -> {
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView,lastPosition)
}
})
}
else -> throw UnsupportedOperationException("This type of RecyclerView.LayoutManager isn't supported")
}
}
}
override fun onDetachedFromRecyclerView(recyclerView: RecyclerView) {
super.onDetachedFromRecyclerView(recyclerView)
recyclerView.clearOnScrollListeners()
}
private fun dispatchVisibleItems(firstPosition: Int,lastPosition: Int) {
val data = currentList
if (visibleItemsListener == null || data.isNullOrEmpty()) return
if (firstPosition != RecyclerView.NO_POSITION && lastPosition != RecyclerView.NO_POSITION && (currentList?.size ?: 0) > 0) {
for (index in firstPosition until lastPosition) {
val item = data[index] ?: continue
if (!itemsShown.containsKey(item)) {
visibleItemsListener.invoke(item)
itemsShown[item] = true
}
}
}
}
布局 XML:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools">
<data>
<import type="android.view.View" />
<variable name="loadingModel" type="com.priceline.android.negotiator.inbox.ui.model.LoadingUIModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeToRefresh"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent" >
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
<include layout="@layout/inbox_empty_msg_view"
android:id="@+id/empty"
android:layout_width="0dp"
android:layout_height="0dp"
android:visibility="@{loadingModel.noMessageVisibility ? View.VISIBLE : View.GONE}"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。