airbnb / epoxy

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

Custom items using EpoxyModelGroup #383

Closed franciscerio closed 6 years ago

franciscerio commented 6 years ago

Hello,

I'm having trouble with EpoxyModelGroup with custom data/pojo(Phase and Entry). I'm using sealed class from kotlin.

Scenario : I want to create a nested recyclerview. In this example, each item has it's own list of items.

Here's my code

list?.forEach {
            when (it) {
                is Phase.PopularPhase -> add(PopularPhaseModelGroup(it.entries))
                is Phase.OpenPhase -> add(OpenPhaseModelGroup(it.entries))
                is Phase.NextPhase -> add(NextPhaseModelGroup(it.entries))
                is Phase.ComingPhase -> add(ComingPhaseModelGroup(it.entries))
                is Phase.FinishedPhase -> add(FinishedPhaseModelGroup(it.entries))
            }

        }

    }

inside PhaseModelGroup and it's the same with other model group.

class OpenPhaseModelGroup constructor(val entries: List<Entry.OpenEntry>) : EpoxyModelGroup(R.layout.item_group_phases2, buildModels(entries)) {
   //hardcoded is a sample id 
    init {
        id(3)
    }
    companion object {
        fun buildModels(entries: List<Entry.OpenEntry>): List<EpoxyModel<*>> {
            val models = mutableListOf<EpoxyModel<*>>()
            val list = ArrayList<OpenItemEntryViewModel_>()
            for (entry in entries) {
                list.add(OpenItemEntryViewModel_().id(entry.id, 3).openEntry(entry))
            }

            models.add(GridCarouselModel_().id("carousel").models(list))
            return models
        }
    }

}

and this is my error or vice versa :

java.lang.ClassCastException: .popular.OpenItemEntryViewModel$ViewHolder cannot be cast to .coming.ComingItemEntryViewModel$ViewHolder
                                                                                     at .coming.ComingItemEntryViewModel_.handlePreBind(ComingItemEntryViewModel_.java:20)

Thanks

elihart commented 6 years ago

Are you using a different layout for each different model class? I see R.layout.item_group_phases2 in your example but not sure what the others use.

The layout is the view type, so it needs to be unique, or else view holders will be shared with other model types.

If you want view type to be unique to each model without worrying about the layout file you can override getViewType in the EpoxyModelGroup and return 0

franciscerio commented 6 years ago

Thank you for your help! Issue fixed.