diff --git a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java b/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java index 54bd1f745b..2085bc96ca 100644 --- a/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java +++ b/epoxy-adapter/src/main/java/com/airbnb/epoxy/EpoxyModelGroup.java @@ -8,6 +8,7 @@ import android.view.ViewStub; import com.airbnb.epoxy.EpoxyModelGroup.Holder; +import com.airbnb.viewmodeladapter.R; import java.util.ArrayList; import java.util.Arrays; @@ -26,6 +27,11 @@ * works fine if you don't need to include any other views, your model views don't need their layout * params changed, and your views don't need ids (eg for saving state). *
+ * Alternatively you can have nested view groups, with the innermost viewgroup given the id + * "epoxy_model_group_child_container" to mark it as the viewgroup that should have the model views + * added to it. The viewgroup marked with this id should be empty. This allows you to nest + * viewgroups, such as a LinearLayout inside of a CardView. + *
* 2. Include a {@link ViewStub} for each of the models in the list. There should be at least as
* many view stubs as models. Extra stubs will be ignored. Each model will be inflated into a view
* stub in order of the view stub's position in the view group. That is, the view group's children
@@ -303,8 +309,10 @@ public class Holder extends EpoxyHolder {
private ViewGroup rootView;
/**
- * Get the root view group that holds all of the model views. You can override {@link
- * EpoxyModelGroup#bind(Holder)} and use this method to make custom changes to the root view.
+ * Get the root view group (aka
+ * {@link android.support.v7.widget.RecyclerView.ViewHolder#itemView}.
+ * You can override {@link EpoxyModelGroup#bind(Holder)} and use this method to make custom
+ * changes to the root view.
*/
public ViewGroup getRootView() {
return rootView;
@@ -317,19 +325,20 @@ protected void bindView(View itemView) {
"The layout provided to EpoxyModelGroup must be a ViewGroup");
}
rootView = (ViewGroup) itemView;
+ ViewGroup childContainer = findChildContainer(rootView);
int modelCount = models.size();
views = new ArrayList<>(modelCount);
holders = new ArrayList<>(modelCount);
- boolean useViewStubs = rootView.getChildCount() != 0;
+ boolean useViewStubs = childContainer.getChildCount() != 0;
for (int i = 0; i < models.size(); i++) {
EpoxyModel model = models.get(i);
View view;
if (useViewStubs) {
- view = replaceNextViewStub(rootView, model, useViewStubLayoutParams(model, i));
+ view = replaceNextViewStub(childContainer, model, useViewStubLayoutParams(model, i));
} else {
- view = createAndAddView(rootView, model);
+ view = createAndAddView(childContainer, model);
}
if (model instanceof EpoxyModelWithHolder) {
@@ -344,6 +353,21 @@ protected void bindView(View itemView) {
}
}
+ /**
+ * By default the outermost viewgroup is used as the container that views are added to. However,
+ * users can specify a different, nested view group to use as the child container by marking it
+ * with a special id.
+ */
+ private ViewGroup findChildContainer(ViewGroup outermostRoot) {
+ View customRoot = outermostRoot.findViewById(R.id.epoxy_model_group_child_container);
+
+ if (customRoot instanceof ViewGroup) {
+ return (ViewGroup) customRoot;
+ }
+
+ return outermostRoot;
+ }
+
private View createAndAddView(ViewGroup groupView, EpoxyModel> model) {
View modelView = model.buildView(groupView);
LayoutParams modelLayoutParams = modelView.getLayoutParams();
diff --git a/epoxy-adapter/src/main/res/values/ids.xml b/epoxy-adapter/src/main/res/values/ids.xml
index ac438fd503..e26d1f737a 100755
--- a/epoxy-adapter/src/main/res/values/ids.xml
+++ b/epoxy-adapter/src/main/res/values/ids.xml
@@ -4,4 +4,5 @@