Skip to content

EpoxyRecyclerView

Eli Hart edited this page Sep 27, 2017 · 14 revisions

Since 2.6.0. This is in Beta, please leave feedback by opening an issue!

Epoxy provides the EpoxyRecyclerView class to enable easy integration between Epoxy and RecyclerView. The goal of this class is to reduce boilerplate in setting up a RecyclerView by applying common defaults. Additionally, several performance optimizations are made.

Improvements in this class are:

  1. A single view pool is automatically shared between all EpoxyRecyclerView instances.

  2. A layout manager is automatically added with sane defaults.

  3. Fixed size is enabled if this view's size is MATCH_PARENT

  4. If a GridLayoutManager is used this will automatically sync the span count with the EpoxyController.

  5. Helper methods to set models without needing to create a EpoxyController class.

  6. Set an EpoxyController and build models in one step

  7. Defaults for usage as a nested recyclerview are provided in Carousel.

  8. Kotlin Extensions

Shared View Pool

To maximize view recycling we share the same view pool across all EpoxyRecyclerView instances in the same Activity.

Also, we do not limit the number of views in the view pool. RecyclerView by default limits the pool to 5 views of each type, but this often does not work for nested RecyclerViews or grids that show more than 5 items in a row, and new views will constantly be created. We prevent this by making the pool size as large as needed for the number of views you need at once.

Default Layout Manager

Normally you have to manually add a LayoutManager to your RecyclerView. This class automatically adds one based on layout param settings.

By default a LinearLayoutManager is used, and a reasonable default is chosen for scrolling direction based on layout params.

If the RecyclerView is set to match_parent size then the scrolling orientation is set to vertical and setHasFixedSize is set to true.

If the height is set to wrap_content then the scrolling orientation is set to horizontal, and setClipToPadding is set to false for carousel usage.

You can subclass EpoxyRecyclerView and override createLayoutManager to establish your own default.

Easily Add Controllers

Normally you need to initialize a RecyclerView and EpoxyController like this

controller = new MyEpoxyController();
recycler.setAdapter(controller.getAdapter());
controller.requestModelBuild();

With EpoxyRecyclerView you can simply do

epoxyRecyclerView.setControllerAndBuildModels(new MyEpoxyController());

Or if you prefer

controller = new MyEpoxyController();
recycler.setController(controller);
controller.requestModelBuild(); // Delay building models until a later time

You can later trigger a model build by calling epoxyRecyclerView.requestModelBuild()

Build Models Without a Controller

Sometimes you may not need the overhead of creating a whole EpoxyController class.

You may instead directly create a list of models and set them on the recycler view

epoxyRecyclerView.setModels(modelsList);

Or you can build models with a lambda

epoxyRecyclerView.buildModelsWith((controller) -> {
  new HeaderModel_()
     .id("header")
     .text("hello world)
     .addTo(controller);
});

You can later trigger a model build by calling epoxyRecyclerView.requestModelBuild()

Kotlin Extensions

With a Kotlin extension function we can further simplify the model building mentioned above to just

epoxyRecyclerView.withModels {
        header {
            ...
        }

        photos.forEach {
            photoView {
                id(it.id)
                url(it.url)
            }
        }
    }

This uses the function

/** Easily add models to an EpoxyRecyclerView, the same way you would in a buildModels method of EpoxyController. */
fun EpoxyRecyclerView.withModels(buildModelsCallback: EpoxyController.() -> Unit) {
    setControllerAndBuildModels(object : EpoxyController() {
        override fun buildModels() {
            buildModelsCallback()
        }
    })
}

to let you build models off a RecyclerView as easily as you would in an EpoxyController. This leverages Epoxy's (generated extension functions](https://github.com/airbnb/epoxy/wiki/Epoxy-Controller#usage-with-kotlin)

Epoxy does not yet package Kotlin extensions, but you can add this to your own project if needed.

Grid Integration

If you are using a GridLayoutManager you normally have to let Epoxy know what the grid span count is and set up the grid span size look up (as detailed here). With EpoxyRecyclerView this span size synchronization is done automatically when you add a GridLayoutManager to the RecyclerView.