package com.airbnb.epoxy.sample.views;
import android.content.Context;
import android.support.annotation.Nullable;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.AttributeSet;
import com.airbnb.epoxy.EpoxyModel;
import com.airbnb.epoxy.SimpleEpoxyController;
import java.util.List;
public class Carousel extends RecyclerView {
private static final int SPAN_COUNT = 2;
private SimpleEpoxyController controller;
private final GridLayoutManager layoutManager;
public Carousel(Context context, @Nullable AttributeSet attrs) {
super(context, attrs);
// Carousels are generally fixed height. Using fixed size is a small optimization we can make
// in that case. This isn't safe to do if the models set in this carousel have varying heights.
setHasFixedSize(true);
// For the example app we use a grid, but in many real world scenarios a simple
// linearlayoutmanager is common. You could modify this carousel code to programmatically
// set the layoutmanager depending on your needs, or hardcode it to a horizontal
// linearlayoutmanager.
layoutManager =
new GridLayoutManager(context, SPAN_COUNT, LinearLayoutManager.HORIZONTAL, false);
setLayoutManager(layoutManager);
}
public void setInitialPrefetchItemCount(int count) {
layoutManager.setInitialPrefetchItemCount(count);
}
public void setModels(List<? extends EpoxyModel<?>> models) {
// If this is the first time setting models we create a new controller. This is because the
// first time a controller builds models it happens right away, otherwise it is posted. We
// need it to happen right away so the models show immediately and so the adapter is
// populated so the carousel scroll state can be restored.
if (controller == null) {
controller = new SimpleEpoxyController();
controller.setSpanCount(SPAN_COUNT);
layoutManager.setSpanSizeLookup(controller.getSpanSizeLookup());
setAdapter(controller.getAdapter());
}
// If the models are set again without being cleared first (eg colors are inserted, shuffled,
// or changed), then reusing the same controller allows diffing to work correctly.
controller.setModels(models);
}
public void clearModels() {
// The controller is cleared so the next time models are set we can create a fresh one.
controller.cancelPendingModelBuild();
controller = null;
// We use swapAdapter instead of setAdapter so that the view pool is not cleared.
// 'removeAndRecycleExistingViews=true' is used
// since the carousel is going off screen and these views can now be recycled to be used in
// another carousel (assuming there is a shared view pool)
swapAdapter(null, true);
}
}