Prefetch and Pagination
This page covers the older Java codegen-based Sections API. If using the Kotlin Lazy Collection API, refer to the interactions docs for Lazy Collection for similar relevant content.
The Working Ranges API provides the means to perform complex operations such as data prefetching and cache warming.
The API extends Sections with a set of appearance and visibility events when a Section enters and exits a given range of positions inside and outside the screen viewport. For example, a network request can be performed to start prefetching data as the last element of a list approaches the viewport.
The API is split into two parts:
- Defining a range - uses a WorkingRange class.
- Receiving range events - events triggered when Sections interact with the defined ranges.
Defining a rangeβ
To use the Working Range API, first, define a WorkingRange class that implements the WorkingRange interface. This is achieved with the following:
public class AtLeastPartiallyVisibleRange implements WorkingRange { ... }
This interface provides two main functions: shouldEnterRange and shouldExitRange.
For both functions, the parameter position
is the position of the item in the list. The firstVisibleIndex
/ lastVisibleIndex
/ firstFullyVisibleIndex
/ lastFullyVisibleIndex
parameters are for the current visible range of the viewport.
Using the shouldEnterRange Functionβ
shouldEnterRange
is used to check if the item is within a user-defined range. The following example checks if that means the position is at least partially visible on screen:
@Override
public boolean shouldEnterRange(
int position,
int firstVisibleIndex,
int lastVisibleIndex,
int firstFullyVisibleIndex,
int lastFullyVisibleIndex) {
return position >= firstVisibleIndex
&& position <= lastVisibleIndex;
}
Using the shouldExitRange Functionβ
shouldExitRange
is used to check if the item is outside of a user-defined range. The following example checks if that means the position is not visible, not even partially:
@Override
public boolean shouldExitRange(
int position,
int firstVisibleIndex,
int lastVisibleIndex,
int firstFullyVisibleIndex,
int lastFullyVisibleIndex) {
return position < firstVisibleIndex
|| position > lastVisibleIndex;
}
For working ranges, the granularity in the ComponentKit is measured with pixels whereas with Litho its positions. This means it's only possible to tell if the component is within a range of positions instead of how many pixels are in the range.
Receiving Range Eventsβ
After defining a working range, the callback functions are implemented inside the components that should receive the exit and enter range events on the @LayoutSpec
that contains the RecyclerComponent
, as follows:
@LayoutSpec
class ListContainerComponentSpec {
@OnRegisterRanges
static void registerWorkingRanges(
ComponentContext c,
@Prop AtLeastPartiallyVisibleRange myRange) {
ListContainerComponent.registerPrefetchWorkingRange(c, myRange);
}
}
The @OnEnteredRange
event is triggered when the component enters the range:
@OnEnteredRange(name = "prefetch")
static void onEnteredWorkingRange(
ComponentContext c,
@Prop MyService service) {
service.startPrefetch();
}
The @OnExitedRange
event is triggered when the component exits the range:
@OnExitedRange(name = "prefetch")
static void onExitedWorkingRange(
ComponentContext c,
@Prop MyService service) {
service.cancelAllPrefetches();
}
The name field in the annotation is used to enable multiple range events for a single layout. For example, 'paginate' becomes registerPaginateWorkingRange
.