airbnb / epoxy

Epoxy is an Android library for building complex screens in a RecyclerView
https://goo.gl/eIK82p
Apache License 2.0
8.47k stars 731 forks source link

[paging3] Expose modelCache #1273

Closed mike-ghes closed 2 years ago

mike-ghes commented 2 years ago

Intended to support two use cases without resorting to reflection:

"Load more" button

This was requested by our designers to leave room for footer content rather than infinite scrolling. Disabling automatic loading can be done just by removing call to super. And to load the next page, we just use modelCache.loadAround():

override fun onModelBound(holder: EpoxyViewHolder, boundModel: EpoxyModel<*>, position: Int, previouslyBoundModel: EpoxyModel<*>?) {
    // Disable automatically loading pages by removing call to super
    // super.onModelBound(holder, boundModel, position, previouslyBoundModel)
}

override fun buildItemModel(currentPosition: Int, item: I?): EpoxyModel<*> {
    if (item == null) {
        return LoadMoreBindingModel_().apply {
            id("load more")
            onClick { _ -> modelCache.loadAround(currentPosition) }
        }
    }
    ...
}

Invalidate item models

An item model may depends on both paging data from remote and some view state. We're able to manually rebuild EpoxyModels for individual items using the modelCache.updateCallback.onChanged().

var seletedItemIds = emptySet()

override fun buildItemModel(currentPosition: Int, item: ItemType?): EpoxyModel<*> {
    return ItemBindingModel_().apply {
        id(item.id)
        selected(seletedItemIds.contains(item.id))
        onClick { _ -> 
            selectedItemIds += item.id
            modelCache.updateCallback.onChanged(currentPosition, 1, null) 
        }
    }
}