diff --git a/CHANGELOG.md b/CHANGELOG.md index fd5f790594..fecfd8cb7e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 1.7.5 (Feb 21, 2017) + +* **New**: Models inherit layouts specified in superclass `@EpoxyModelClass` annotations [#119](https://github.com/airbnb/epoxy/pull/119) +* **New**: Support module configuration options [#124](https://github.com/airbnb/epoxy/pull/124) + # 1.6.2 (Feb 8, 2017) * New: Support layout resource annotations in library projects (https://github.com/airbnb/epoxy/pull/116) diff --git a/README.md b/README.md index cae31e0764..71e7638261 100755 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Epoxy is an Android library for building complex screens in a RecyclerView. It a * [Hiding Models](#hiding-models) * [Saving View State](#saved-state) * [Grid Support](#grid-support) +* [Configuration](#configuration) * [Generating Models via Annotations](#annotations) * [Sample App](/epoxy-sample) @@ -30,15 +31,15 @@ Gradle is the only supported build configuration, so just add the dependency to ```groovy dependencies { - compile 'com.airbnb.android:epoxy:1.6.2' + compile 'com.airbnb.android:epoxy:1.7.5' } ``` Optionally, if you want to use the [attributes for generated helper classes](#annotations) you must also provide the annotation processor as a dependency. ```groovy dependencies { - compile 'com.airbnb.android:epoxy:1.6.2' - annotationProcessor 'com.airbnb.android:epoxy-processor:1.6.2' + compile 'com.airbnb.android:epoxy:1.7.5' + annotationProcessor 'com.airbnb.android:epoxy-processor:1.7.5' } ``` @@ -387,6 +388,26 @@ epoxyAdapter.setSpanCount(spanCount); layoutManager.setSpanSizeLookup(epoxyAdapter.getSpanSizeLookup()); ``` +## Configuration + +Use the `@PackageEpoxyConfig` package annotation to specify configuration options for all models in a package. + +```java +@PackageEpoxyConfig( + requireAbstractModels = true, + requireHashCode = true +) +package com.example.app; + +import com.airbnb.epoxy.PackageEpoxyConfig; +``` + +These configuration options are used by the annotation processor to enforce model requirements or influence how generated models are created. + +This is especially useful for larger projects with many models and/or contributors. In these cases having a standardized pattern for models greatly reduces mistakes in creating and using models. + +If a config annotation is not found in a package then the configuration from the nearest parent package will be used. If no parent packages declare a configuration then the default values are used. See the `PackageEpoxyConfig` source for up to date documentation on supported configuration options and their defaults. + ## Generating Models via Annotations You can reduce boilerplate in your model classes by using the `EpoxyModelClass` and `EpoxyAttribute` annotations to generate a subclass of your model. diff --git a/epoxy-annotations/src/main/java/com/airbnb/epoxy/PackageEpoxyConfig.java b/epoxy-annotations/src/main/java/com/airbnb/epoxy/PackageEpoxyConfig.java index 5133f3c45c..65dbbc6045 100644 --- a/epoxy-annotations/src/main/java/com/airbnb/epoxy/PackageEpoxyConfig.java +++ b/epoxy-annotations/src/main/java/com/airbnb/epoxy/PackageEpoxyConfig.java @@ -19,7 +19,8 @@ boolean REQUIRE_ABSTRACT_MODELS = false; /** * If true, all fields marked with {@link com.airbnb.epoxy.EpoxyAttribute} must have a type that - * implements hashCode, or the attribute must set hash=false. + * implements hashCode (besides the default Object implementation), or the attribute must set + * hash=false. *
* Setting this to true is useful for ensuring that all model attributes correctly implement * hashCode, or use hash=false (eg for click listeners). It is a common mistake to miss these, @@ -28,13 +29,12 @@ * The check is done at compile time and compilation will fail if a hashCode validation fails. *
* Since it is done at compile time this can only check the direct type of the field. Interfaces - * will fail the check even if an implementation of that interface which does implement hashCode - * is used at runtime. + * or classes will pass the check if they either have an abstract hashCode method (since it is + * assumed that the object at runtime will implement it) or their class hierarchy must have an + * implementation of hashCode besides the default Object implementation. *
- * If an attribute is an Iterable or Array then that collection type must implement hashCode. - *
- * If the attribute type is a class that uses Google AutoValue then the hashCode check will
- * succeed, since it is assumed that a generated subclass of that type will be used.
+ * If an attribute is an Iterable or Array then the type of object in that collection must
+ * implement hashCode.
*/
boolean requireHashCode() default REQUIRE_HASHCODE_DEFAULT;
/**
diff --git a/epoxy-sample/src/main/java/com/airbnb/epoxy/models/ColorModel.java b/epoxy-sample/src/main/java/com/airbnb/epoxy/models/ColorModel.java
index 1fe368bc94..16831650ee 100644
--- a/epoxy-sample/src/main/java/com/airbnb/epoxy/models/ColorModel.java
+++ b/epoxy-sample/src/main/java/com/airbnb/epoxy/models/ColorModel.java
@@ -4,8 +4,9 @@
import android.view.View;
import com.airbnb.epoxy.EpoxyAttribute;
+import com.airbnb.epoxy.EpoxyModel;
+import com.airbnb.epoxy.EpoxyModelClass;
import com.airbnb.epoxy.R;
-import com.airbnb.epoxy.SimpleEpoxyModel;
/**
* This is an example of using {@link com.airbnb.epoxy.SimpleEpoxyModel}, which is useful if you
@@ -13,17 +14,16 @@
* com.airbnb.epoxy.SimpleEpoxyModel} directly instead of subclassing it if you don't need to do
* anything in onBind.
*/
-public class ColorModel extends SimpleEpoxyModel {
+@EpoxyModelClass(layout = R.layout.model_color)
+public abstract class ColorModel extends EpoxyModel