@@ -12,9 +12,8 @@ Before using this library, you should be familiar with the following topics:
12
12
1 . [ Data model] ( #data-model )
13
13
1 . [ Querying] ( #querying )
14
14
1 . [ Populating a RecyclerView] ( #using-firebaseui-to-populate-a-recyclerview )
15
- 1 . [ Using the adapter] ( #using-the-firebaserecycleradapter )
16
- 1 . [ Adapter lifecyle] ( #firebaserecycleradapter-lifecycle )
17
- 1 . [ Events] ( #data-and-error-events )
15
+ 1 . [ Using the FirebaseRecyclerAdapter] ( #using-the-firebaserecycleradapter )
16
+ 1 . [ Using the FirebaseRecyclerPagingAdapter] ( #using-the-firebaserecyclerpagingadapter )
18
17
1 . [ Populating a ListView] ( #using-firebaseui-to-populate-a-listview )
19
18
1 . [ Handling indexed data] ( #using-firebaseui-with-indexed-data )
20
19
1 . [ Warnings] ( #a-note-on-ordering )
@@ -115,6 +114,17 @@ This means implementing a custom `RecyclerView.Adapter` and coordinating updates
115
114
116
115
Fear not, FirebaseUI does all of this for you automatically!
117
116
117
+ ### Choosing an adapter
118
+
119
+ FirebaseUI offers two types of RecyclerView adapters for the Realtime Database:
120
+
121
+ * ` FirebaseRecyclerAdapter ` — binds a ` Query ` to a ` RecyclerView ` and responds to all real-time
122
+ events included items being added, removed, moved, or changed. Best used with small result sets
123
+ since all results are loaded at once.
124
+ * ` FirebasePagingRecyclerAdapter ` — binds a ` Query ` to a ` RecyclerView ` by loading data in pages. Best
125
+ used with large, static data sets. Real-time events are not respected by this adapter, so it
126
+ will not detect new/removed items or changes to items already loaded.
127
+
118
128
### Using the FirebaseRecyclerAdapter
119
129
120
130
The ` FirebaseRecyclerAdapter ` binds a ` Query ` to a ` RecyclerView ` . When data is added, removed,
@@ -169,9 +179,9 @@ Finally attach the adapter to your `RecyclerView` with the `RecyclerView#setAdap
169
179
Don't forget to also set a ` LayoutManager ` !
170
180
171
181
172
- ### FirebaseRecyclerAdapter lifecycle
182
+ #### FirebaseRecyclerAdapter lifecycle
173
183
174
- #### Start/stop listening
184
+ ##### Start/stop listening
175
185
176
186
The ` FirebaseRecyclerAdapter ` uses an event listener to monitor changes to the Firebase query.
177
187
To begin listening for data, call the ` startListening() ` method. You may want to call this in your
@@ -197,15 +207,15 @@ protected void onStop() {
197
207
}
198
208
```
199
209
200
- #### Automatic listening
210
+ ##### Automatic listening
201
211
202
212
If you don't want to manually start/stop listening you can use
203
213
[ Android Architecture Components] [ arch-components ] to automatically manage the lifecycle of the
204
214
` FirebaseRecyclerAdapter ` . Pass a ` LifecycleOwner ` to
205
215
` FirebaseRecyclerOptions.Builder#setLifecycleOwner(...) ` and FirebaseUI will automatically
206
216
start and stop listening in ` onStart() ` and ` onStop() ` .
207
217
208
- ### Data and error events
218
+ #### Data and error events
209
219
210
220
When using the ` FirebaseRecyclerAdapter ` you may want to perform some action every time data
211
221
changes or when there is an error. To do this, override the ` onDataChanged() ` and ` onError() `
@@ -231,6 +241,156 @@ FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(
231
241
};
232
242
```
233
243
244
+ ### Using the ` FirebaseRecyclerPagingAdapter `
245
+
246
+ The ` FirebaseRecyclerPagingAdapter ` binds a ` Query ` to a ` RecyclerView ` by loading documents in pages.
247
+ This results in a time and memory efficient binding, however it gives up the real-time events
248
+ afforted by the ` FirestoreRecyclerAdapter ` .
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:
252
+
253
+ ``` groovy
254
+ implementation 'android.arch.paging:runtime:1.x.x'
255
+ ```
256
+
257
+ First, configure the adapter by building ` DatabasePagingOptions ` . Since the paging adapter
258
+ is not appropriate for a chat application (it would not detect new messages), we will consider
259
+ an adapter that loads a generic ` Item ` :
260
+
261
+ ``` java
262
+ // The "base query" is a query with no startAt/endAt/limit clauses that the adapter can use
263
+ // to form smaller queries for each page.
264
+ Query baseQuery = mDatabase. getReference(). child(" items" );
265
+
266
+ // This configuration comes from the Paging Support Library
267
+ // https://developer.android.com/reference/android/arch/paging/PagedList.Config.html
268
+ PagedList . Config config = new PagedList .Config .Builder ()
269
+ .setEnablePlaceholders(false )
270
+ .setPrefetchDistance(10 )
271
+ .setPageSize(20 )
272
+ .build();
273
+
274
+ // The options for the adapter combine the paging configuration with query information
275
+ // and application-specific options for lifecycle, etc.
276
+ DatabasePagingOptions<Item > options = new DatabasePagingOptions .Builder<Item > ()
277
+ .setLifecycleOwner(this )
278
+ .setQuery(baseQuery, config, Item . class)
279
+ .build();
280
+ ```
281
+
282
+ If you need to customize how your model class is parsed, you can use a custom ` SnapshotParser ` :
283
+
284
+ ``` java
285
+ .. . setQuery(... , new SnapshotParser<Item > () {
286
+ @NonNull
287
+ @Override
288
+ public Item parseSnapshot (@NonNull DocumentSnapshot snapshot ) {
289
+ return ... ;
290
+ }
291
+ });
292
+ ```
293
+
294
+ Next, create the ` FirebaseRecyclerPagingAdapter ` object. You should already have a ` ViewHolder ` subclass
295
+ for displaying each item. In this case we will use a custom ` ItemViewHolder ` class:
296
+
297
+ ``` java
298
+ FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > adapter =
299
+ new FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > (options) {
300
+ @NonNull
301
+ @Override
302
+ public ItemViewHolder onCreateViewHolder (@NonNull ViewGroup parent , int viewType ) {
303
+ // Create the ItemViewHolder
304
+ // ...
305
+ }
306
+
307
+ @Override
308
+ protected void onBindViewHolder (@NonNull ItemViewHolder holder ,
309
+ int position ,
310
+ @NonNull Item model ) {
311
+ // Bind the item to the view holder
312
+ // ...
313
+ }
314
+ };
315
+ ```
316
+
317
+ Finally attach the adapter to your ` RecyclerView ` with the ` RecyclerView#setAdapter() ` method.
318
+ Don't forget to also set a ` LayoutManager ` !
319
+
320
+ #### ` FirebaseRecyclerPagingAdapter ` lifecycle
321
+
322
+ ##### Start/stop listening
323
+
324
+ The ` FirebaseRecyclerPagingAdapter ` listens for scrolling events and loads additional pages from the
325
+ database only when needed.
326
+
327
+ To begin populating data, call the ` startListening() ` method. You may want to call this
328
+ in your ` onStart() ` method. Make sure you have finished any authentication necessary to read the
329
+ data before calling ` startListening() ` or your query will fail.
330
+
331
+ ``` java
332
+ @Override
333
+ protected void onStart() {
334
+ super . onStart();
335
+ adapter. startListening();
336
+ }
337
+ ```
338
+
339
+ Similarly, the ` stopListening() ` call freezes the data in the ` RecyclerView ` and prevents any future
340
+ loading of data pages.
341
+
342
+ Call this method when the containing Activity or Fragment stops:
343
+
344
+ ``` java
345
+ @Override
346
+ protected void onStop() {
347
+ super . onStop();
348
+ adapter. stopListening();
349
+ }
350
+ ```
351
+
352
+ ##### Automatic listening
353
+
354
+ If you don't want to manually start/stop listening you can use
355
+ [ Android Architecture Components] [ arch-components ] to automatically manage the lifecycle of the
356
+ ` FirebaseRecyclerPagingAdapter ` . Pass a ` LifecycleOwner ` to
357
+ ` DatabasePagingOptions.Builder#setLifecycleOwner(...) ` and FirebaseUI will automatically
358
+ start and stop listening in ` onStart() ` and ` onStop() ` .
359
+
360
+ #### Paging events
361
+
362
+ 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:
365
+
366
+ ``` java
367
+ FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > adapter =
368
+ new FirebaseRecyclerPagingAdapter<Item , ItemViewHolder > (options) {
369
+
370
+ // ...
371
+
372
+ @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
380
+ // ...
381
+ case LOADED :
382
+ // The previous load (either initial or additional) completed
383
+ // ...
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
+ // ...
388
+ }
389
+ }
390
+ };
391
+ ```
392
+
393
+
234
394
## Using FirebaseUI to populate a ` ListView `
235
395
236
396
ListView is the older, yet simpler way to handle lists of items. Using it is analogous to
0 commit comments