初始加载后更新PagedListAdapter以显示最新的网络数据

时间:2018-06-26 03:49:21

标签: android kotlin paging

我正在使用新的Paging库从rest API加载分页数据,但是我在理解如何将新数据缓存到Room中后如何继续加载它们时遇到了麻烦。目前,我有一个PagedListAdapter,它通过使用边界回调从API加载项目进行更新,然后将这些项目存储在本地DB(Room)中,并通过可流动对象发送到UI。

BoundaryCallback的

onZeroItemsLoaded和onItemAtEndLoaded调用均按预期运行,但仅适用于初始加载。一旦检索到数据并将其存储在缓存(Room)中,我将永远不会从网络服务中获取新数据-缓存中已经有数据,并且不会触发边界回调。

如何使用分页库将项目标记为过时,以便每次应用打开时我的数据都是新鲜的?

ItemCallback.kt:

class ItemBoundaryCallback : PagedList.BoundaryCallback<Item>() {
        override fun onZeroItemsLoaded() {
            itemsFromNetwork(0)
        }

        override fun onItemAtEndLoaded(itemAtEnd: Item) {
            itemsFromNetwork(itemAtEnd.rank)
        }
    }

ItemRepository.kt:

fun items(): Flowable<PagedList<Item>> {
    return RxPagedListBuilder(database.itemDao().items(), pageSize)
            .setBoundaryCallback(boundaryCallback)
            .buildFlowable(BackpressureStrategy.LATEST)
}

ItemDao.kt

@Query("SELECT * FROM item ORDER BY rank ASC")
fun items(): DataSource.Factory<Int, Item>

ItemAdapter.kt

class ItemAdapter() : PagedListAdapter<Item, ItemViewHolder>(diffCallback) {
    companion object {
        private val diffCallback = object : DiffUtil.ItemCallback<Item>() {
            override fun areItemsTheSame(old: Item, new: Item): Boolean = old.id == new.id
            override fun areContentsTheSame(old: Item, new: Item): Boolean = old == new
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ItemViewHolder {
        return ItemViewHolder(LayoutInflater.from(parent.context).inflate(R.layout.r_item, parent, false))
    }

    override fun onBindViewHolder(viewHolder: ItemViewHolder, position: Int) {
        viewHolder.bind(getItem(position), clickListener)
    }
}

ItemFragment.kt

override fun onStart() {
    super.onStart()

    itemRepository.items()
            .subscribe(itemAdapter::submitList)
            .addTo(disposables)

1 个答案:

答案 0 :(得分:1)

使用此技术的重点(数据库和其余部分)是缓存数据并防止再次加载它们。 但是,如果您的数据不是静态的,并且可能被更改或无效。 您可以采用两种方法:

1-关闭应用程序后(或启动应用程序时,删除数据库中的所有记录。destroy回调不可行),在这种情况下,下次启动后您将获得新数据。

2-在数据库中将字段设置为“到期”日期或类似的日期。继续检查onItemAtFrontLoadedboundaryCallback上的字段是否过期,您可以使其无效并再次从Web服务中获取它。