Skip to content

Visibility Events

Eli Hart edited this page Oct 12, 2018 · 7 revisions

Since 2.19.0

Epoxy supports notifying callbacks when views scroll on and off of the screen. Visibility state is defined with these terms.

  • Visible: Triggered when at least one pixel of the view is visible.
  • Invisible: Triggered when the view no longer has any pixels on the screen.
  • Focused: Event: Triggered when either the view occupies at least half of the viewport, or, if the view is smaller than half the viewport, when it is fully visible.
  • Unfocused Visible: Triggered when the view is no longer focused, i.e. it is not fully visible and does not occupy at least half the viewport.
  • Full Impression Visible: Triggered when the entire view has passed through the viewport at some point.

Callbacks for visibility changes

There are two interfaces that communicate visibility status.

OnModelVisibilityStateChangedListener - This notifies you when the visibility state of the view changes, such as going from invisible to visible.

OnModelVisibilityChangedListener - This is a more granular callback that tells you exactly how much of the view is visible on screen.

Registering callbacks

There are several ways to register callbacks for the two visibility interfaces.

When building a model

When you instantiate a generated model and set your data on it you can register visibility listeners for that specific model instance

new MyModel_()
   .id("my id")
   .onVisibilityStateChanged { model, view, visibilityState ->
      // Do something with the new visibility state
   } 
   .onVisibilityChanged { model, view, percentVisibleHeight, percentVisibleWidth, visibleHeight, visibleWidth ,view -> 
      // Do something with the visibility information
  }

When overriding a model

If you are creating your own EpoxyModel subclass (such as a model that uses a viewholder) then you can override the visibility callbacks directly to get notified of all events for models of that type.

class MyModel extends EpoxyModelWithHolder<Holder> {
  ... // Set up your model as usual
  
  // Override these visibility callbacks as needed

  public void onVisibilityStateChanged(@Visibility int visibilityState, @NonNull T view) {

  }

  public void onVisibilityChanged(
      @FloatRange(from = 0.0f, to = 100.0f) float percentVisibleHeight,
      @FloatRange(from = 0.0f, to = 100.0f) float percentVisibleWidth,
      @Px int visibleHeight,
      @Px int visibleWidth,
      @NonNull T view
  ) {

  }
}

Within custom views with @ModelView

If you are using the @ModelView annotation to generate models from custom views then you can annotate methods within your view to receive visibility callbacks directly in the view.

There are two annotations, one for each callback type.

OnVisibilityStateChanged

OnVisibilityChanged

You must make sure that your annotated methods have the correct signature, otherwise Epoxy will provide an error at compile time. Usage looks like:

@ModelView
class MyView extends View {

@OnVisibilityStateChange
void myMethodForWatchingVisibilityState(@VisibilityState int state) {

}

@OnVisibilityStateChanged
void myMethodForWatchingVisibility(
    float percentVisibleHeight, float percentVisibleWidth,
    int visibleHeight, int visibleWidth
){

}