简体   繁体   中英

How to avoid requestModelBuild for every widgets in a recyclerview

I have a recycler view with fixed number widgets vertically in a specific order. Some of the widgets also contain tabular data hence I've considered using nested recycler view also within it.

Every widget makes http call asynchronously from the ViewModel and binds the data to the epoxyController as I mentioned below.

As requestModelBuild() being called for every widget as they receive the data through the public setters for example priceViewData, packageData and etc from where requestModelBuild() is called. So in this instance every widget bind happens regardless of every time when data is received for any of the widgets. This seems to be expensive also, there some analytics gets fired as we needed for every bind.

So, here the analytics call for the widget is multiplied. Please suggest if this can be handled through the epoxy without handling manually.

class ProductDetailsEpoxyController(val view: View?,
                              private val name: String?,
                              private val context: Context?) : 
 AsyncEpoxyController() {

private val args = bundleOf("name" to name)

var priceViewData: IndicativePriceViewData? = emptyPriceViewData()
    set(value) {
        field = value
        requestModelBuild()
    }

var packageData: PackageViewData? = emptyPackageWidgetViewData()
    set(value) {
        field = value
        requestModelBuild()
    }

   ...
   ...



override fun buildModels() {
    buildPriceViewData()
    buildPackageViewData()
    ....
}

private fun buildPriceViewData(){
    priceViewData?.let {
        id("price")
        priceViewDataModel(it)
    }
}

private fun buildPackageViewData(){
    packageViewData?.let {
         id("package")
          packageViewDataModel(it)
    }
}

  ...
  ...

 }

From Epoxy's Wiki :

Adapter and diffing details Once models are built, Epoxy sets the new models on the backing adapter and runs a diffing algorithm to compute changes against the previous model list. Any item changes are notified to the RecyclerView so that views can be removed, inserted, moved, or updated as necessary.

So basicallly, this ensures not all models will be updated.

The issue that you're facing is possibly related to:

  1. Using DataBinding
  2. Your classes are not implemented equals and hashCode the way you want.

The problem with using Objects in DataBinding is that, every time the object is updated, all fields that depend on the object are also updated, even if not all changed.

If your classes are normal classes and not data classes or you expect a different behavior when executing priceData1 == priceData2 (for example, only comparing the data's id), you should override this methods so Epoxy detect changes correctly. Also, you can use DoNotHash option for EpoxyAttribute so the class is not added to the model's hashCode function. More info

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM