@@ -121,7 +121,7 @@ FirebaseUI offers two types of RecyclerView adapters for the Realtime Database:
121
121
* ` FirebaseRecyclerAdapter ` — binds a ` Query ` to a ` RecyclerView ` and responds to all real-time
122
122
events included items being added, removed, moved, or changed. Best used with small result sets
123
123
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
125
125
used with large, static data sets. Real-time events are not respected by this adapter, so it
126
126
will not detect new/removed items or changes to items already loaded.
127
127
@@ -245,13 +245,13 @@ FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(
245
245
246
246
The ` FirebaseRecyclerPagingAdapter ` binds a ` Query ` to a ` RecyclerView ` by loading documents in pages.
247
247
This 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 ` .
249
249
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:
252
252
253
253
``` groovy
254
- implementation 'androidx.paging:paging-runtime:2 .x.x'
254
+ implementation 'androidx.paging:paging-runtime:3 .x.x'
255
255
```
256
256
257
257
First, configure the adapter by building ` DatabasePagingOptions ` . Since the paging adapter
@@ -263,13 +263,10 @@ an adapter that loads a generic `Item`:
263
263
// to form smaller queries for each page.
264
264
Query baseQuery = mDatabase. getReference(). child(" items" );
265
265
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 );
273
270
274
271
// The options for the adapter combine the paging configuration with query information
275
272
// and application-specific options for lifecycle, etc.
@@ -360,34 +357,98 @@ start and stop listening in `onStart()` and `onStop()`.
360
357
#### Paging events
361
358
362
359
When 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:
365
361
366
- ``` java
367
- FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > adapter =
368
- new FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > (options) {
362
+ ##### In Java
369
363
370
- // ...
364
+ Use the ` addLoadStateListener ` method from the adapter:
371
365
366
+ ``` java
367
+ adapter. addLoadStateListener(new Function1<CombinedLoadStates , Unit > () {
372
368
@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
380
393
// ...
381
- case LOADED :
394
+ return null ;
395
+ }
396
+
397
+ if (refresh instanceof LoadState . NotLoading ) {
382
398
// The previous load (either initial or additional) completed
383
399
// ...
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
+ }
388
402
}
403
+ return null ;
389
404
}
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
+ }
391
452
```
392
453
393
454
@@ -458,4 +519,4 @@ The order in which you receive your data depends on the order from `keyRef`, not
458
519
[ indexed-data ] : https://firebase.google.com/docs/database/android/structure-data#best_practices_for_data_structure
459
520
[ recyclerview ] : https://developer.android.com/reference/androidx/recyclerview/widget/RecyclerView
460
521
[ 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