Skip to content

Commit 09f6a6d

Browse files
committed
Break out Page
Change-Id: I2be8141c859ba84994b4d9eeb624d2893aa02c3a
1 parent 51c0d95 commit 09f6a6d

File tree

2 files changed

+171
-116
lines changed

2 files changed

+171
-116
lines changed

firestore/src/main/java/com/firebase/ui/firestore/FirestorePagingAdapter.java

Lines changed: 45 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,12 @@
22

33
import android.support.annotation.NonNull;
44
import android.support.annotation.Nullable;
5-
import android.support.annotation.RestrictTo;
65
import android.support.v7.widget.RecyclerView;
76
import android.util.Log;
87
import android.view.ViewGroup;
98

10-
import com.google.android.gms.tasks.OnCompleteListener;
11-
import com.google.android.gms.tasks.Task;
129
import com.google.firebase.firestore.DocumentSnapshot;
1310
import com.google.firebase.firestore.Query;
14-
import com.google.firebase.firestore.QuerySnapshot;
1511

1612
import java.util.ArrayList;
1713
import java.util.List;
@@ -23,7 +19,8 @@
2319
* See also {@link FirestoreInfiniteScrollListener}.
2420
*/
2521
public abstract class FirestorePagingAdapter<T, VH extends RecyclerView.ViewHolder>
26-
extends RecyclerView.Adapter<VH> {
22+
extends RecyclerView.Adapter<VH>
23+
implements Page.Listener {
2724

2825
private static final String TAG = "FirestorePagingAdapter";
2926

@@ -42,7 +39,7 @@ public FirestorePagingAdapter(FirestorePagingOptions<T> options) {
4239
mParser = options.getParser();
4340
mForwardQuery = options.getQuery();
4441

45-
Page page = new Page(0);
42+
Page page = new Page(0, this);
4643
mPages.add(page);
4744

4845
onLoadingStateChanged(true);
@@ -74,7 +71,7 @@ public void onBindViewHolder(VH holder, int position) {
7471
public int getPagesLoaded() {
7572
int count = 0;
7673
for (Page page : mPages) {
77-
if (page.getState() == PageState.LOADED) {
74+
if (page.getState() == Page.State.LOADED) {
7875
count++;
7976
}
8077
}
@@ -89,13 +86,13 @@ public int getPagesLoaded() {
8986
* specified in the options, unload the bottom-most page.
9087
*/
9188
public void loadPageUp() {
92-
if (countState(PageState.LOADING) > 0) {
89+
if (hasAny(Page.State.LOADING)) {
9390
return;
9491
}
9592

9693
// Load the last UNLOADED page before the middle "core" of LOADED pages
97-
int firstLoaded = findFirstOfState(PageState.LOADED);
98-
int lastUnloadedBefore = findLastOfState(PageState.UNLOADED, firstLoaded);
94+
int firstLoaded = findFirstOfState(Page.State.LOADED);
95+
int lastUnloadedBefore = findLastOfState(Page.State.UNLOADED, firstLoaded);
9996

10097
if (lastUnloadedBefore != -1) {
10198
logd("RELOADING " + lastUnloadedBefore);
@@ -120,15 +117,15 @@ public void loadPageUp() {
120117
* specified in the options, unload the top-most page.
121118
*/
122119
public void loadNextPage() {
123-
if (countState(PageState.LOADING) > 0) {
120+
if (hasAny(Page.State.LOADING)) {
124121
return;
125122
}
126123

127124
// There are two cases here
128125
// 1. Need to load a whole new page
129126
// 2. Need to load an UNLOADED bottom page
130127

131-
int lastLoaded = findLastOfState(PageState.LOADED);
128+
int lastLoaded = findLastOfState(Page.State.LOADED);
132129

133130
if (lastLoaded == mPages.size() - 1) {
134131
// Case 1: Load a new page at the bottom
@@ -143,7 +140,7 @@ public void loadNextPage() {
143140

144141
// Add and start loading
145142
int nextPageIndex = mPages.size();
146-
Page nextPage = new Page(nextPageIndex);
143+
Page nextPage = new Page(nextPageIndex, this);
147144
mPages.add(nextPage);
148145

149146
logd("LOADING " + nextPageIndex);
@@ -152,7 +149,7 @@ public void loadNextPage() {
152149
} else {
153150
// Case 2: Need to load a previously unloaded page
154151
// Find the first UNLOADED page after the middle "core" of loaded pages
155-
int firstUnloadedAfter = findFirstOfState(PageState.UNLOADED, lastLoaded);
152+
int firstUnloadedAfter = findFirstOfState(Page.State.UNLOADED, lastLoaded);
156153

157154
logd("RELOADING " + firstUnloadedAfter);
158155
Page page = mPages.get(firstUnloadedAfter);
@@ -214,29 +211,50 @@ public T get(int index) {
214211
return mParser.parseSnapshot(getSnapshot(index));
215212
}
216213

214+
@Override
215+
public void onPageStateChanged(Page page, Page.State state) {
216+
if (state == Page.State.LOADING) {
217+
onLoadingStateChanged(true);
218+
} else {
219+
onLoadingStateChanged(hasAny(Page.State.LOADING));
220+
}
221+
222+
if (state == Page.State.LOADED) {
223+
onPageLoaded(page.getIndex(), page.size());
224+
}
225+
226+
if (state == Page.State.UNLOADED) {
227+
onPageUnloaded(page.getIndex(), page.size());
228+
}
229+
}
230+
231+
@Override
232+
public void onPageError(Page page, Exception ex) {
233+
Log.w(TAG, "Failed to get page", ex);
234+
// TODO: Remove page?
235+
}
236+
217237
/**
218238
* Called when a page begins or finishes loading, to indicate if there are any current loading
219239
* operations going on.
220240
*
221241
* Useful to override and control UI elements such as a progress bar or loading spinner.
222-
* @param isLoading
223242
*/
224-
// TODO: Better interface
225243
protected void onLoadingStateChanged(boolean isLoading) {
226244
// No-op, this is for overriding.
227245
}
228246

229247
private void unloadTopPage() {
230248
// Find first loaded page
231-
int firstLoaded = findFirstOfState(PageState.LOADED);
249+
int firstLoaded = findFirstOfState(Page.State.LOADED);
232250
if (firstLoaded != -1) {
233251
mPages.get(firstLoaded).unload();
234252
logd("UNLOADING " + firstLoaded);
235253
}
236254
}
237255

238256
private void unloadBottomPage() {
239-
int lastLoaded = findLastOfState(PageState.LOADED);
257+
int lastLoaded = findLastOfState(Page.State.LOADED);
240258
if (lastLoaded != -1) {
241259
mPages.get(lastLoaded).unload();
242260
logd("UNLOADING " + lastLoaded);
@@ -251,7 +269,7 @@ private void onPageLoaded(int index, int size) {
251269

252270
notifyItemRangeInserted(itemsBefore, size);
253271

254-
if (countState(PageState.LOADING) > 0) {
272+
if (hasAny(Page.State.LOADING)) {
255273
onLoadingStateChanged(true);
256274
} else {
257275
onLoadingStateChanged(false);
@@ -267,11 +285,11 @@ private void onPageUnloaded(int index, int size) {
267285
notifyItemRangeRemoved(itemsBefore, size);
268286
}
269287

270-
private int findFirstOfState(PageState state) {
288+
private int findFirstOfState(Page.State state) {
271289
return findFirstOfState(state, 0);
272290
}
273291

274-
private int findFirstOfState(PageState state, int startingAt) {
292+
private int findFirstOfState(Page.State state, int startingAt) {
275293
for (int i = startingAt; i < mPages.size(); i++) {
276294
Page page = mPages.get(i);
277295
if (page.getState() == state) {
@@ -282,11 +300,11 @@ private int findFirstOfState(PageState state, int startingAt) {
282300
return -1;
283301
}
284302

285-
private int findLastOfState(PageState state) {
303+
private int findLastOfState(Page.State state) {
286304
return findLastOfState(state, mPages.size() - 1);
287305
}
288306

289-
private int findLastOfState(PageState state, int endingAt) {
307+
private int findLastOfState(Page.State state, int endingAt) {
290308
for (int i = endingAt; i >= 0; i--) {
291309
Page page = mPages.get(i);
292310
if (page.getState() == state) {
@@ -297,15 +315,14 @@ private int findLastOfState(PageState state, int endingAt) {
297315
return -1;
298316
}
299317

300-
private int countState(PageState state) {
301-
int count = 0;
318+
private boolean hasAny(Page.State state) {
302319
for (Page page : mPages) {
303320
if (page.getState() == state) {
304-
count++;
321+
return true;
305322
}
306323
}
307324

308-
return count;
325+
return false;
309326
}
310327

311328
@Nullable
@@ -350,97 +367,9 @@ private Query queryAfter(@Nullable DocumentSnapshot startAfter) {
350367
return query;
351368
}
352369

353-
private void logd(String message) {
370+
private static void logd(String message) {
354371
if (Log.isLoggable(TAG, Log.DEBUG)) {
355372
Log.d(TAG, message);
356373
}
357374
}
358-
359-
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
360-
private enum PageState {
361-
LOADING,
362-
LOADED,
363-
UNLOADED
364-
}
365-
366-
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
367-
private class Page implements OnCompleteListener<QuerySnapshot> {
368-
369-
private final int mIndex;
370-
private PageState mState;
371-
private DocumentSnapshot mFirstSnapshot;
372-
373-
private List<DocumentSnapshot> mSnapshots = new ArrayList<>();
374-
375-
public Page(int index) {
376-
mIndex = index;
377-
mState = PageState.UNLOADED;
378-
}
379-
380-
public void load(Query query) {
381-
if (mState == PageState.LOADING) {
382-
return;
383-
}
384-
385-
mState = PageState.LOADING;
386-
onLoadingStateChanged(true);
387-
query.get().addOnCompleteListener(this);
388-
}
389-
390-
public void unload() {
391-
int size = mSnapshots.size();
392-
mSnapshots.clear();
393-
394-
onPageUnloaded(mIndex, size);
395-
mState = PageState.UNLOADED;
396-
}
397-
398-
@Override
399-
public void onComplete(@NonNull Task<QuerySnapshot> task) {
400-
// TODO: Better error handling
401-
if (!task.isSuccessful()) {
402-
Log.w(TAG, "Failed to get page", task.getException());
403-
}
404-
405-
// Add all snapshots
406-
mSnapshots.addAll(task.getResult().getDocuments());
407-
408-
// Set first in page
409-
if (mSnapshots.isEmpty()) {
410-
mFirstSnapshot = null;
411-
} else {
412-
mFirstSnapshot = mSnapshots.get(0);
413-
}
414-
415-
// Mark page as loaded
416-
logd("LOADED " + mIndex);
417-
mState = PageState.LOADED;
418-
onPageLoaded(mIndex, mSnapshots.size());
419-
}
420-
421-
public PageState getState() {
422-
return mState;
423-
}
424-
425-
public DocumentSnapshot get(int index) {
426-
return mSnapshots.get(index);
427-
}
428-
429-
public int size() {
430-
return mSnapshots.size();
431-
}
432-
433-
@Nullable
434-
public DocumentSnapshot getFirst() {
435-
return mFirstSnapshot;
436-
}
437-
438-
@Nullable
439-
public DocumentSnapshot getLast() {
440-
if (mSnapshots == null || mSnapshots.isEmpty()) {
441-
return null;
442-
}
443-
return mSnapshots.get(mSnapshots.size() - 1);
444-
}
445-
}
446375
}

0 commit comments

Comments
 (0)