Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize model group partial binding #316

Merged
merged 1 commit into from
Oct 14, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 48 additions & 15 deletions epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ private EpoxyModelGroup(@LayoutRes int layoutRes, List<? extends EpoxyModel<?>>
public void handlePostBind(Holder groupHolder, final int position) {
iterateModels(groupHolder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
if (model instanceof GeneratedModel) {
//noinspection unchecked
((GeneratedModel) model).handlePostBind(boundObject, position);
Expand All @@ -124,7 +124,7 @@ public void onModel(EpoxyModel model, Object boundObject, View view) {
public void handlePreBind(final EpoxyViewHolder holder, Holder groupHolder, final int position) {
iterateModels(groupHolder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
if (model instanceof GeneratedModel) {
//noinspection unchecked
((GeneratedModel) model).handlePreBind(holder, boundObject, position);
Expand All @@ -138,7 +138,7 @@ public void onModel(EpoxyModel model, Object boundObject, View view) {
public void bind(Holder holder) {
iterateModels(holder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
setViewVisibility(model, view);
//noinspection unchecked
model.bind(boundObject);
Expand All @@ -151,10 +151,39 @@ public void onModel(EpoxyModel model, Object boundObject, View view) {
public void bind(Holder holder, final List<Object> payloads) {
iterateModels(holder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
setViewVisibility(model, view);
//noinspection unchecked
model.bind(boundObject, payloads);
model.bind(boundObject);
}
});
}

@Override
public void bind(Holder holder, EpoxyModel<?> previouslyBoundModel) {
if (!(previouslyBoundModel instanceof EpoxyModelGroup)) {
bind(holder);
return;
}

final EpoxyModelGroup previousGroup = (EpoxyModelGroup) previouslyBoundModel;
if (previousGroup.models.size() != models.size()) {
throw createInconsistentModelCountException();
}

iterateModels(holder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
setViewVisibility(model, view);

EpoxyModel<?> previousModel = previousGroup.models.get(modelIndex);
if (previousModel.id() == model.id()) {
//noinspection unchecked
model.bind(boundObject, previousModel);
} else {
//noinspection unchecked
model.bind(boundObject);
}
}
});
}
Expand All @@ -172,7 +201,7 @@ private static void setViewVisibility(EpoxyModel model, View view) {
public void unbind(Holder holder) {
iterateModels(holder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
//noinspection unchecked
model.unbind(boundObject);
}
Expand All @@ -184,7 +213,7 @@ public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onViewAttachedToWindow(Holder holder) {
iterateModels(holder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
//noinspection unchecked
model.onViewAttachedToWindow(boundObject);
}
Expand All @@ -196,7 +225,7 @@ public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onViewDetachedFromWindow(Holder holder) {
iterateModels(holder, new IterateModelsCallback() {
@Override
public void onModel(EpoxyModel model, Object boundObject, View view) {
public void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex) {
//noinspection unchecked
model.onViewDetachedFromWindow(boundObject);
}
Expand All @@ -206,11 +235,7 @@ public void onModel(EpoxyModel model, Object boundObject, View view) {
private void iterateModels(Holder holder, IterateModelsCallback callback) {
int modelCount = models.size();
if (modelCount != holder.views.size()) {
throw new IllegalStateException(
"The number of models used in this group has changed. The model count must remain "
+ "constant if the same layout resource is used. If you need to change which models"
+ " are shown you can call EpoxyMode#hide() to have a model's view hidden, or use a"
+ " different layout resource for the group.");
throw createInconsistentModelCountException();
}

for (int i = 0; i < modelCount; i++) {
Expand All @@ -219,12 +244,20 @@ private void iterateModels(Holder holder, IterateModelsCallback callback) {
EpoxyHolder epoxyHolder = holder.holders.get(i);
Object objectToBind = (model instanceof EpoxyModelWithHolder) ? epoxyHolder : view;

callback.onModel(model, objectToBind, view);
callback.onModel(model, objectToBind, view, i);
}
}

private RuntimeException createInconsistentModelCountException() {
return new IllegalStateException(
"The number of models used in this group has changed. The model count must remain "
+ "constant if the same layout resource is used. If you need to change which models"
+ " are shown you can call EpoxyMode#hide() to have a model's view hidden, or use a"
+ " different layout resource for the group.");
}

private interface IterateModelsCallback {
void onModel(EpoxyModel model, Object boundObject, View view);
void onModel(EpoxyModel model, Object boundObject, View view, int modelIndex);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,24 @@ private static List<EpoxyModel<?>> buildModels(CarouselData carousel,
ArrayList<EpoxyModel<?>> models = new ArrayList<>();

models.add(new ImageButtonModel_()
.id("add")
.imageRes(R.drawable.ic_add_circle)
.clickListener(v -> callbacks.onAddColorToCarouselClicked(carousel)));

models.add(new ImageButtonModel_()
.id("delete")
.imageRes(R.drawable.ic_delete)
.clickListener(v -> callbacks.onClearCarouselClicked(carousel))
.show(colors.size() > 0));

models.add(new ImageButtonModel_()
.id("change")
.imageRes(R.drawable.ic_change)
.clickListener(v -> callbacks.onChangeCarouselColorsClicked(carousel))
.show(colors.size() > 0));

models.add(new ImageButtonModel_()
.id("shuffle")
.imageRes(R.drawable.ic_shuffle)
.clickListener(v -> callbacks.onShuffleCarouselColorsClicked(carousel))
.show(colors.size() > 1));
Expand All @@ -59,7 +63,9 @@ private static List<EpoxyModel<?>> buildModels(CarouselData carousel,
}));
}

models.add(new GridCarouselModel_().models(colorModels));
models.add(new GridCarouselModel_()
.id("carousel")
.models(colorModels));

return models;
}
Expand Down