@@ -12,9 +12,8 @@ Before using this library, you should be familiar with the following topics:
12121 . [ Data model] ( #data-model )
13131 . [ Querying] ( #querying )
14141 . [ 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 )
18171 . [ Populating a ListView] ( #using-firebaseui-to-populate-a-listview )
19181 . [ Handling indexed data] ( #using-firebaseui-with-indexed-data )
2019 1 . [ Warnings] ( #a-note-on-ordering )
@@ -115,6 +114,17 @@ This means implementing a custom `RecyclerView.Adapter` and coordinating updates
115114
116115Fear not, FirebaseUI does all of this for you automatically!
117116
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+
118128### Using the FirebaseRecyclerAdapter
119129
120130The ` 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
169179Don't forget to also set a ` LayoutManager ` !
170180
171181
172- ### FirebaseRecyclerAdapter lifecycle
182+ #### FirebaseRecyclerAdapter lifecycle
173183
174- #### Start/stop listening
184+ ##### Start/stop listening
175185
176186The ` FirebaseRecyclerAdapter ` uses an event listener to monitor changes to the Firebase query.
177187To begin listening for data, call the ` startListening() ` method. You may want to call this in your
@@ -197,15 +207,15 @@ protected void onStop() {
197207}
198208```
199209
200- #### Automatic listening
210+ ##### Automatic listening
201211
202212If you don't want to manually start/stop listening you can use
203213[ Android Architecture Components] [ arch-components ] to automatically manage the lifecycle of the
204214` FirebaseRecyclerAdapter ` . Pass a ` LifecycleOwner ` to
205215` FirebaseRecyclerOptions.Builder#setLifecycleOwner(...) ` and FirebaseUI will automatically
206216start and stop listening in ` onStart() ` and ` onStop() ` .
207217
208- ### Data and error events
218+ #### Data and error events
209219
210220When using the ` FirebaseRecyclerAdapter ` you may want to perform some action every time data
211221changes or when there is an error. To do this, override the ` onDataChanged() ` and ` onError() `
@@ -231,6 +241,156 @@ FirebaseRecyclerAdapter adapter = new FirebaseRecyclerAdapter<Chat, ChatHolder>(
231241};
232242```
233243
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+
234394## Using FirebaseUI to populate a ` ListView `
235395
236396ListView is the older, yet simpler way to handle lists of items. Using it is analogous to
0 commit comments