-
- All Implemented Interfaces:
-
com.airbnb.epoxy.ModelCollector,com.airbnb.epoxy.stickyheader.StickyHeaderCallbacks
public abstract class EpoxyController implements ModelCollector, StickyHeaderCallbacks
A controller for easily combining EpoxyModel instances in a RecyclerView.Adapter. Simply implement buildModels to declare which models should be used, and in which order. Call requestModelBuild whenever your data changes, and the controller will call buildModels, update the adapter with the new models, and notify any changes between the new and old models.
The controller maintains a androidx.recyclerview.widget.RecyclerView.Adapter with the latest models, which you can get via getAdapter to set on your RecyclerView.
All data change notifications are applied automatically via Epoxy's diffing algorithm. All of your models must have a unique id set on them for diffing to work. You may choose to use annotations to have the controller create models with unique ids for you automatically.
Once a model is created and added to the controller in buildModels it should be treated as immutable and never modified again. This is necessary for adapter updates to be accurate.
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description public interfaceEpoxyController.InterceptorA callback that is run after buildModels completes and before diffing is run.
public interfaceEpoxyController.ExceptionHandler
-
Field Summary
Fields Modifier and Type Field Description public static HandlerdefaultModelBuildingHandlerpublic static HandlerdefaultDiffingHandlerprivate static booleanglobalDebugLoggingEnabledprivate final EpoxyControllerAdapteradapterprivate volatile booleanfilterDuplicatesprivate static EpoxyController.ExceptionHandlerglobalExceptionHandler
-
Constructor Summary
Constructors Constructor Description EpoxyController()EpoxyController(Handler modelBuildingHandler, Handler diffingHandler)
-
Method Summary
Modifier and Type Method Description static voidsetGlobalDebugLoggingEnabled(boolean globalDebugLoggingEnabled)Similar to setDebugLoggingEnabled, but this changes the global default forall EpoxyControllers. EpoxyControllerAdaptergetAdapter()Get the underlying adapter built by this controller. voidsetFilterDuplicates(boolean filterDuplicates)If set to true, Epoxy will search for models with duplicate ids added during and remove any duplicates found. static voidsetGlobalExceptionHandler(@NonNull() EpoxyController.ExceptionHandler globalExceptionHandler)Set a callback to be notified when a recoverable exception occurs at runtime. voidrequestModelBuild()Call this to request a model update. booleanhasPendingModelBuild()Whether an update to models is currently pending. voidaddModelBuildListener(OnModelBuildFinishedListener listener)Add a listener that will be called every time buildModels has finished runningand changes have been dispatched to the RecyclerView. voidremoveModelBuildListener(OnModelBuildFinishedListener listener)Remove a listener added with addModelBuildListener. synchronized voidrequestDelayedModelBuild(int delayMs)Call this to request a delayed model update. synchronized voidcancelPendingModelBuild()Cancels a pending call to buildModels if one has been queued by . voidaddInterceptor(@NonNull() EpoxyController.Interceptor interceptor)Add an interceptor callback to be run after models are built, to make any last changes beforethey are set on the adapter. voidremoveInterceptor(@NonNull() EpoxyController.Interceptor interceptor)Remove an interceptor that was added with addInterceptor. voidadd(@NonNull() EpoxyModel<out Object> model)Add the model to this controller. booleanisDuplicateFilteringEnabled()static voidsetGlobalDuplicateFilteringDefault(boolean filterDuplicatesByDefault)setFilterDuplicates is disabled in each EpoxyController by default. voidsetDebugLoggingEnabled(boolean enabled)If enabled, DEBUG logcat messages will be printed to show when models are rebuilt, the timetaken to build them, the time taken to diff them, and the item change outcomes from thediffer. booleanisDebugLoggingEnabled()voidmoveModel(int fromPosition, int toPosition)An optimized way to move a model from one position to another without rebuilding all models. voidnotifyModelChanged(int position)An way to notify the adapter that a model has changed. voidonSaveInstanceState(@NonNull() Bundle outState)voidonRestoreInstanceState(@Nullable() Bundle inState)GridLayoutManager.SpanSizeLookupgetSpanSizeLookup()For use with a grid layout manager - use this to get the SpanSizeLookup for models inthis controller. voidsetSpanCount(int spanCount)If you are using a grid layout manager you must call this to set the span count of the grid.This span count will be passed on to the models so models can choose which span count to be. intgetSpanCount()booleanisMultiSpan()voidsetupStickyHeaderView(@NotNull() View stickyHeader)Optional callback to setup the sticky view,by default it doesn't do anything.The sub-classes should override the function if they areusing sticky header feature. voidteardownStickyHeaderView(@NotNull() View stickyHeader)Optional callback to perform tear down operation on thesticky view, by default it doesn't do anything.The sub-classes should override the function if they areusing sticky header feature. booleanisStickyHeader(int position)Called to check if the item at the position is a sticky item,by default returns false.The sub-classes should override the function if they areusing sticky header feature. -
Methods inherited from class com.airbnb.epoxy.ModelCollector
add -
Methods inherited from class com.airbnb.epoxy.stickyheader.StickyHeaderCallbacks
isStickyHeader, setupStickyHeaderView, teardownStickyHeaderView -
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
-
Method Detail
-
setGlobalDebugLoggingEnabled
static void setGlobalDebugLoggingEnabled(boolean globalDebugLoggingEnabled)
Similar to setDebugLoggingEnabled, but this changes the global default forall EpoxyControllers.
The default is false.
-
getAdapter
@NonNull() EpoxyControllerAdapter getAdapter()
Get the underlying adapter built by this controller. Use this to get the adapter to set on aRecyclerView, or to get information about models currently in use.
-
setFilterDuplicates
void setFilterDuplicates(boolean filterDuplicates)
If set to true, Epoxy will search for models with duplicate ids added during and remove any duplicates found. If models with the same id are found, thefirst one is left in the adapter and any subsequent models are removed. will be called for each duplicate removed.
This may be useful if your models are created via server supplied data, in which case theserver may erroneously send duplicate items. Duplicate items are otherwise left in and canresult in undefined behavior.
-
setGlobalExceptionHandler
static void setGlobalExceptionHandler(@NonNull() EpoxyController.ExceptionHandler globalExceptionHandler)
Set a callback to be notified when a recoverable exception occurs at runtime. By default theseare ignored and Epoxy will recover, but you can override this to be aware of when they happen.
For example, you could choose to rethrow the exception in development builds, or log them inproduction.
A common use for this is being aware of duplicates when setFilterDuplicates is enabled.
This callback will be used in all EpoxyController classes. If you would like specific handlingin a certain controller you can override onExceptionSwallowed inthat controller.
-
requestModelBuild
void requestModelBuild()
Call this to request a model update. The controller will schedule a call to so that models can be rebuilt for the current data. Once a build is requestedall subsequent requests are ignored until the model build runs. Therefore, the calling codeneed not worry about calling this multiple times in a row.
The exception is that the first time this is called on a new instance of it is run synchronously. This allows state to be restored and the initial viewto be draw quicker.
If you would like to be alerted when models have finished building use addModelBuildListener
-
hasPendingModelBuild
boolean hasPendingModelBuild()
Whether an update to models is currently pending. This can either be because requestModelBuild was called, or because models are currently being built or diffon a background thread.
-
addModelBuildListener
void addModelBuildListener(OnModelBuildFinishedListener listener)
Add a listener that will be called every time buildModels has finished runningand changes have been dispatched to the RecyclerView.
Since buildModels can be called once for many calls to requestModelBuild, this iscalled just once for each buildModels execution, not for every request.
Use this to react to changes in your models that need to happen after the RecyclerView hasbeen notified, such as scrolling.
-
removeModelBuildListener
void removeModelBuildListener(OnModelBuildFinishedListener listener)
Remove a listener added with addModelBuildListener.This is safe to call from inside the callback onModelBuildFinished
-
requestDelayedModelBuild
synchronized void requestDelayedModelBuild(int delayMs)
Call this to request a delayed model update. The controller will schedule a call to so that models can be rebuilt for the current data.
Using this to delay a model update may be helpful in cases where user input is causing manyrapid changes in the models, such as typing. In that case, the view is already updated onscreen and constantly rebuilding models is potentially slow and unnecessary. The downside todelaying the model build too long is that models will not be in sync with the data or view, andscrolling the view offscreen and back onscreen will cause the model to bind old data.
If a previous request is still pending it will be removed in favor of this new delay
Any call to requestModelBuild will override a delayed request.
In most cases you should use requestModelBuild instead of this.
- Parameters:
delayMs- The time in milliseconds to delay the model build by.
-
cancelPendingModelBuild
synchronized void cancelPendingModelBuild()
-
addInterceptor
void addInterceptor(@NonNull() EpoxyController.Interceptor interceptor)
Add an interceptor callback to be run after models are built, to make any last changes beforethey are set on the adapter. Interceptors are run in the order they are added.
Interceptors are run on the same thread that models are built on.
-
removeInterceptor
void removeInterceptor(@NonNull() EpoxyController.Interceptor interceptor)
Remove an interceptor that was added with addInterceptor.
-
add
void add(@NonNull() EpoxyModel<out Object> model)
Add the model to this controller. Can only be called from inside .
-
isDuplicateFilteringEnabled
boolean isDuplicateFilteringEnabled()
-
setGlobalDuplicateFilteringDefault
static void setGlobalDuplicateFilteringDefault(boolean filterDuplicatesByDefault)
setFilterDuplicates is disabled in each EpoxyController by default. It can betoggled individually in each controller, or alternatively you can use this to change thedefault value for all EpoxyControllers.
-
setDebugLoggingEnabled
void setDebugLoggingEnabled(boolean enabled)
If enabled, DEBUG logcat messages will be printed to show when models are rebuilt, the timetaken to build them, the time taken to diff them, and the item change outcomes from thediffer. The tag of the logcat message is the class name of your EpoxyController.
This is useful to verify that models are being diffed as expected, as well as to watch forslowdowns in model building or diffing to indicate when you should optimize model building ormodel hashCode/equals implementations (which can often slow down diffing).
This should only be used in debug builds to avoid a performance hit in prod.
-
isDebugLoggingEnabled
boolean isDebugLoggingEnabled()
-
moveModel
void moveModel(int fromPosition, int toPosition)
An optimized way to move a model from one position to another without rebuilding all models.This is intended to be used with androidx.recyclerview.widget.ItemTouchHelper toallow for efficient item dragging and rearranging. It cannot be
If you call this you MUST also update the data backing your models as necessary.
This will immediately change the model's position and notify the change to the RecyclerView.However, a delayed request to rebuild models will be scheduled for the future to guarantee thatmodels are in sync with data.
- Parameters:
fromPosition- Previous position of the item.toPosition- New position of the item.
-
notifyModelChanged
void notifyModelChanged(int position)
An way to notify the adapter that a model has changed. This is intended to be used with androidx.recyclerview.widget.ItemTouchHelper to allow revert swiping a model.
This will immediately notify the change to the RecyclerView.
- Parameters:
position- Position of the item.
-
onSaveInstanceState
void onSaveInstanceState(@NonNull() Bundle outState)
-
onRestoreInstanceState
void onRestoreInstanceState(@Nullable() Bundle inState)
-
getSpanSizeLookup
@NonNull() GridLayoutManager.SpanSizeLookup getSpanSizeLookup()
For use with a grid layout manager - use this to get the SpanSizeLookup for models inthis controller. This will delegate span look up calls to each model's . Make sure to also call setSpanCount sothe span count is correct.
-
setSpanCount
void setSpanCount(int spanCount)
If you are using a grid layout manager you must call this to set the span count of the grid.This span count will be passed on to the models so models can choose which span count to be.
-
getSpanCount
int getSpanCount()
-
isMultiSpan
boolean isMultiSpan()
-
setupStickyHeaderView
void setupStickyHeaderView(@NotNull() View stickyHeader)
Optional callback to setup the sticky view,by default it doesn't do anything.The sub-classes should override the function if they areusing sticky header feature.
-
teardownStickyHeaderView
void teardownStickyHeaderView(@NotNull() View stickyHeader)
Optional callback to perform tear down operation on thesticky view, by default it doesn't do anything.The sub-classes should override the function if they areusing sticky header feature.
-
isStickyHeader
boolean isStickyHeader(int position)
Called to check if the item at the position is a sticky item,by default returns false.The sub-classes should override the function if they areusing sticky header feature.
-
-
-
-