@@ -121,7 +121,7 @@ FirebaseUI offers two types of RecyclerView adapters for the Realtime Database:
121121 * ` FirebaseRecyclerAdapter ` — binds a ` Query ` to a ` RecyclerView ` and responds to all real-time
122122 events included items being added, removed, moved, or changed. Best used with small result sets
123123 since all results are loaded at once.
124- * ` FirebasePagingRecyclerAdapter ` — binds a ` Query ` to a ` RecyclerView ` by loading data in pages. Best
124+ * ` FirebaseRecyclerPagingAdapter ` — binds a ` Query ` to a ` RecyclerView ` by loading data in pages. Best
125125 used with large, static data sets. Real-time events are not respected by this adapter, so it
126126 will not detect new/removed items or changes to items already loaded.
127127
@@ -245,13 +245,13 @@ FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(
245245
246246The ` FirebaseRecyclerPagingAdapter ` binds a ` Query ` to a ` RecyclerView ` by loading documents in pages.
247247This results in a time and memory efficient binding, however it gives up the real-time events
248- afforded by the ` FirestoreRecyclerAdapter ` .
248+ afforded by the ` FirebaseRecyclerAdapter ` .
249249
250- The ` FirebaseRecyclerPagingAdapter ` is built on top of the [ Android Paging Support Library] [ paging-support ] .
251- Before using the adapter in your application, you must add a dependency on the support library:
250+ The ` FirebaseRecyclerPagingAdapter ` is built on top of the [ Android Paging 3 Library] [ paging-support ] .
251+ Before using the adapter in your application, you must add a dependency on that library:
252252
253253``` groovy
254- implementation 'androidx.paging:paging-runtime:2 .x.x'
254+ implementation 'androidx.paging:paging-runtime:3 .x.x'
255255```
256256
257257First, configure the adapter by building ` DatabasePagingOptions ` . Since the paging adapter
@@ -263,13 +263,10 @@ an adapter that loads a generic `Item`:
263263// to form smaller queries for each page.
264264Query baseQuery = mDatabase. getReference(). child(" items" );
265265
266- // This configuration comes from the Paging Support Library
267- // https://developer.android.com/reference/androidx/paging/PagedList.Config
268- PagedList . Config config = new PagedList .Config .Builder ()
269- .setEnablePlaceholders(false )
270- .setPrefetchDistance(10 )
271- .setPageSize(20 )
272- .build();
266+ // This configuration comes from the Paging 3 Library
267+ // https://developer.android.com/reference/kotlin/androidx/paging/PagingConfig
268+ PagingConfig config = new PagingConfig (/* page size */ 20 , /* prefetchDistance */ 10 ,
269+ /* enablePlaceHolders */ false );
273270
274271// The options for the adapter combine the paging configuration with query information
275272// and application-specific options for lifecycle, etc.
@@ -360,34 +357,98 @@ start and stop listening in `onStart()` and `onStop()`.
360357#### Paging events
361358
362359When using the ` FirebaseRecyclerPagingAdapter ` , you may want to perform some action every time data
363- changes or when there is an error. To do this, override the ` onLoadingStateChanged() `
364- method of the adapter:
360+ changes or when there is an error. To do this:
365361
366- ``` java
367- FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > adapter =
368- new FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > (options) {
362+ ##### In Java
369363
370- // ...
364+ Use the ` addLoadStateListener ` method from the adapter:
371365
366+ ``` java
367+ adapter. addLoadStateListener(new Function1<CombinedLoadStates , Unit > () {
372368 @Override
373- protected void onLoadingStateChanged (@NonNull LoadingState state ) {
374- switch (state) {
375- case LOADING_INITIAL :
376- // The initial load has begun
377- // ...
378- case LOADING_MORE :
379- // The adapter has started to load an additional page
369+ public Unit invoke (CombinedLoadStates states ) {
370+ LoadState refresh = states. getRefresh();
371+ LoadState append = states. getAppend();
372+
373+ if (refresh instanceof LoadState . Error || append instanceof LoadState . Error ) {
374+ // The previous load (either initial or additional) failed. Call
375+ // the retry() method in order to retry the load operation.
376+ // ...
377+ }
378+
379+ if (refresh instanceof LoadState . Loading ) {
380+ // The initial Load has begun
381+ // ...
382+ }
383+
384+ if (append instanceof LoadState . Loading ) {
385+ // The adapter has started to load an additional page
386+ // ...
387+ }
388+
389+ if (append instanceof LoadState . NotLoading ) {
390+ LoadState . NotLoading notLoading = (LoadState . NotLoading ) append;
391+ if (notLoading. getEndOfPaginationReached()) {
392+ // The adapter has finished loading all of the data set
380393 // ...
381- case LOADED :
394+ return null ;
395+ }
396+
397+ if (refresh instanceof LoadState . NotLoading ) {
382398 // The previous load (either initial or additional) completed
383399 // ...
384- case ERROR :
385- // The previous load (either initial or additional) failed. Call
386- // the retry() method in order to retry the load operation.
387- // ...
400+ return null ;
401+ }
388402 }
403+ return null ;
389404 }
390- };
405+ });
406+ ```
407+
408+ #### In Kotlin
409+
410+ Use the ` loadStateFlow ` exposed by the adapter, in a Coroutine Scope:
411+
412+ ``` kotlin
413+ // Activities can use lifecycleScope directly, but Fragments should instead use
414+ // viewLifecycleOwner.lifecycleScope.
415+ lifecycleScope.launch {
416+ pagingAdapter.loadStateFlow.collectLatest { loadStates ->
417+ when (loadStates.refresh) {
418+ is LoadState .Error -> {
419+ // The initial load failed. Call the retry() method
420+ // in order to retry the load operation.
421+ // ...
422+ }
423+ is LoadState .Loading -> {
424+ // The initial Load has begun
425+ // ...
426+ }
427+ }
428+
429+ when (loadStates.append) {
430+ is LoadState .Error -> {
431+ // The additional load failed. Call the retry() method
432+ // in order to retry the load operation.
433+ // ...
434+ }
435+ is LoadState .Loading -> {
436+ // The adapter has started to load an additional page
437+ // ...
438+ }
439+ is LoadState .NotLoading -> {
440+ if (loadStates.append.endOfPaginationReached) {
441+ // The adapter has finished loading all of the data set
442+ // ...
443+ }
444+ if (loadStates.refresh is LoadState .NotLoading ) {
445+ // The previous load (either initial or additional) completed
446+ // ...
447+ }
448+ }
449+ }
450+ }
451+ }
391452```
392453
393454
@@ -458,4 +519,4 @@ The order in which you receive your data depends on the order from `keyRef`, not
458519[ indexed-data ] : https://firebase.google.com/docs/database/android/structure-data#best_practices_for_data_structure
459520[ recyclerview ] : https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView
460521[ arch-components ] : https://developer.android.com/topic/libraries/architecture/index.html
461- [ paging-support ] : https://developer.android.com/topic/libraries/architecture/paging
522+ [ paging-support ] : https://developer.android.com/topic/libraries/architecture/paging/v3-overview
0 commit comments