我正在使用Android Jetpack分页库(2.1.2)进行聊天。 通过使用PagedList.BoundaryCallback机制从本地数据库(房间)和网络提供数据。由于会议室向RecyclerView适配器提供了分页数据,所以我无法滚动到列表底部,因为列表大小未知。
我还为适配器注册了 registerAdapterDataObserver ,以观察更改。然而 onItemRangeInserted 回调中的itemCount值不时更改。
那么当您将PagedListAdapter与BoundaryCallback一起使用时,你们如何滚动到RecyclerView的底部?
答案 0 :(得分:0)
为此,我们需要扩展位置数据源,并覆盖loadInitial()方法。基本上,房间使用sqlite中的限制和偏移量从特定位置加载特定范围的数据。代码在Kotlin中,但是可以在Java中轻松理解和转换
private fun scrollToBottom() {
val position = adapter.itemCount - 1
if (position > 0) {
recyclerView.scrollToPosition(0)
}
}
在上面的代码中,我们强迫房间(当然,您必须实现自己的Dao,它只使用了我前面提到的offset和limit)将位置0的初始数据加载到newRequestedSize,即分页库希望我们加载的当前偏移量和加载大小的总和。一次,我们将数据从位置0加载到当前页面位置,我们需要使用数据和位置0设置回调。现在,分页库将数据加载到当前页面位置和我们的
init {
val tableObserver = object : InvalidationTracker.Observer(tableName) {
override fun onInvalidated(tables: MutableSet<String>) {
// invalidate the dataSource
Log.v("dataSource invalidate requested!")
invalidate()
}
}
database.invalidationTracker.addObserver(tableObserver)
addInvalidatedCallback {
Log.v("invalidation callback received, removing table observer")
database.invalidationTracker.removeObserver(tableObserver)
}
}
功能按预期工作。 我们还需要处理的一件事是监听表更改,您可以再次在LimitOffsetDatasource中找到有关房间如何进行更改的信息。
.carousel-item {
transition: opacity 1s ease-in-out !important;
}
li{
transition: opacity 1s ease !important;
}
这种方法对性能有影响,但是在我们这种情况下,用户大部分时间都在消息传递中,该消息始终位于第一页。因此,当用户处于最底层时,此实现与LimitOffsetDatasource的实现相同。仅当用户滚动查看旧消息并且同时有新消息到达用户时,我们才将所有消息重新加载到用户当前位置。但是,当新消息到达时,用户很可能会滚动到底部。因此,性能损失几乎为零。