Skip to content

Commit d170531

Browse files
PatilShreyassamtstern
authored andcommitted
Realtime Database Pagination (#1603)
1 parent 7c631c4 commit d170531

File tree

15 files changed

+910
-2
lines changed

15 files changed

+910
-2
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@
5555
<activity
5656
android:name=".database.realtime.RealtimeDbChatActivity"
5757
android:label="@string/title_realtime_database_activity" />
58+
59+
<!-- Realtime database paging demo -->
60+
<activity
61+
android:name=".database.realtime.FirebaseDbPagingActivity"
62+
android:label="@string/title_paging_database_activity" />
63+
5864
<activity
5965
android:name=".database.realtime.RealtimeDbChatIndexActivity"
6066
android:label="@string/title_realtime_database_activity" />

app/src/main/java/com/firebase/uidemo/ChooserActivity.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import com.firebase.uidemo.auth.AuthUiActivity;
3333
import com.firebase.uidemo.database.firestore.FirestoreChatActivity;
3434
import com.firebase.uidemo.database.firestore.FirestorePagingActivity;
35+
import com.firebase.uidemo.database.realtime.FirebaseDbPagingActivity;
3536
import com.firebase.uidemo.database.realtime.RealtimeDbChatActivity;
3637
import com.firebase.uidemo.storage.ImageActivity;
3738

@@ -71,6 +72,7 @@ private static class ActivityChooserAdapter
7172
FirestoreChatActivity.class,
7273
FirestorePagingActivity.class,
7374
RealtimeDbChatActivity.class,
75+
FirebaseDbPagingActivity.class,
7476
ImageActivity.class,
7577
};
7678

@@ -80,6 +82,7 @@ private static class ActivityChooserAdapter
8082
R.string.title_firestore_activity,
8183
R.string.title_firestore_paging_activity,
8284
R.string.title_realtime_database_activity,
85+
R.string.title_paging_database_activity,
8386
R.string.title_storage_activity
8487
};
8588

@@ -89,6 +92,7 @@ private static class ActivityChooserAdapter
8992
R.string.desc_firestore,
9093
R.string.desc_firestore_paging,
9194
R.string.desc_realtime_database,
95+
R.string.desc_paging_database,
9296
R.string.desc_storage
9397
};
9498

Lines changed: 161 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,161 @@
1+
package com.firebase.uidemo.database.realtime;
2+
3+
import android.arch.paging.PagedList;
4+
import android.os.Bundle;
5+
import android.support.annotation.NonNull;
6+
import android.support.annotation.Nullable;
7+
import android.support.v4.widget.SwipeRefreshLayout;
8+
import android.support.v7.app.AppCompatActivity;
9+
import android.support.v7.widget.LinearLayoutManager;
10+
import android.support.v7.widget.RecyclerView;
11+
import android.util.Log;
12+
import android.view.LayoutInflater;
13+
import android.view.View;
14+
import android.view.ViewGroup;
15+
import android.widget.TextView;
16+
import android.widget.Toast;
17+
18+
import com.firebase.ui.database.paging.DatabasePagingOptions;
19+
import com.firebase.ui.database.paging.FirebaseRecyclerPagingAdapter;
20+
import com.firebase.ui.database.paging.LoadingState;
21+
import com.firebase.uidemo.R;
22+
import com.google.firebase.database.DatabaseError;
23+
import com.google.firebase.database.FirebaseDatabase;
24+
import com.google.firebase.database.Query;
25+
26+
import butterknife.BindView;
27+
import butterknife.ButterKnife;
28+
29+
public class FirebaseDbPagingActivity extends AppCompatActivity {
30+
31+
private final String TAG = "PagingActivity";
32+
33+
@BindView(R.id.paging_recycler)
34+
RecyclerView mRecycler;
35+
36+
@BindView(R.id.swipe_refresh_layout)
37+
SwipeRefreshLayout mSwipeRefreshLayout;
38+
39+
private Query mQuery;
40+
41+
@Override
42+
protected void onCreate(@Nullable Bundle savedInstanceState) {
43+
super.onCreate(savedInstanceState);
44+
setContentView(R.layout.activity_database_paging);
45+
ButterKnife.bind(this);
46+
47+
mQuery = FirebaseDatabase.getInstance().getReference().child("posts");
48+
49+
setUpAdapter();
50+
}
51+
52+
private void setUpAdapter() {
53+
54+
//Initialize Paging Configurations
55+
PagedList.Config config = new PagedList.Config.Builder()
56+
.setEnablePlaceholders(false)
57+
.setPrefetchDistance(5)
58+
.setPageSize(30)
59+
.build();
60+
61+
//Initialize Firebase Paging Options
62+
DatabasePagingOptions<Post> options = new DatabasePagingOptions.Builder<Post>()
63+
.setLifecycleOwner(this)
64+
.setQuery(mQuery, config, Post.class)
65+
.build();
66+
67+
//Initializing Adapter
68+
final FirebaseRecyclerPagingAdapter<Post, PostViewHolder> mAdapter =
69+
new FirebaseRecyclerPagingAdapter<Post, PostViewHolder>(options) {
70+
@NonNull
71+
@Override
72+
public PostViewHolder onCreateViewHolder(@NonNull ViewGroup parent,
73+
int viewType) {
74+
View view = LayoutInflater.from(parent.getContext())
75+
.inflate(R.layout.item_post, parent, false);
76+
return new PostViewHolder(view);
77+
}
78+
79+
@Override
80+
protected void onBindViewHolder(@NonNull PostViewHolder holder,
81+
int position,
82+
@NonNull Post model) {
83+
holder.bind(model);
84+
}
85+
86+
@Override
87+
protected void onLoadingStateChanged(@NonNull LoadingState state) {
88+
switch (state) {
89+
case LOADING_INITIAL:
90+
case LOADING_MORE:
91+
mSwipeRefreshLayout.setRefreshing(true);
92+
break;
93+
94+
case LOADED:
95+
mSwipeRefreshLayout.setRefreshing(false);
96+
break;
97+
98+
case FINISHED:
99+
mSwipeRefreshLayout.setRefreshing(false);
100+
Toast.makeText(getApplicationContext(), getString(R.string.paging_finished_message), Toast.LENGTH_SHORT).show();
101+
break;
102+
103+
case ERROR:
104+
retry();
105+
break;
106+
}
107+
}
108+
109+
@Override
110+
protected void onError(DatabaseError databaseError) {
111+
mSwipeRefreshLayout.setRefreshing(false);
112+
Log.e(TAG, databaseError.getMessage());
113+
}
114+
};
115+
116+
mRecycler.setLayoutManager(new LinearLayoutManager(this));
117+
mRecycler.setAdapter(mAdapter);
118+
119+
// Reload data on swipe
120+
mSwipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
121+
@Override
122+
public void onRefresh() {
123+
//Reload Data
124+
mAdapter.refresh();
125+
}
126+
});
127+
}
128+
129+
public static class Post {
130+
131+
@Nullable public String title;
132+
@Nullable public String body;
133+
134+
public Post(){}
135+
136+
public Post(@Nullable String title, @Nullable String body) {
137+
this.title = title;
138+
this.body = body;
139+
}
140+
}
141+
142+
public static class PostViewHolder extends RecyclerView.ViewHolder {
143+
144+
@BindView(R.id.textViewTitle)
145+
TextView mTitleView;
146+
147+
@BindView(R.id.textViewBody)
148+
TextView mBodyView;
149+
150+
PostViewHolder(@NonNull View itemView) {
151+
super(itemView);
152+
ButterKnife.bind(this, itemView);
153+
}
154+
155+
void bind(@NonNull Post post) {
156+
mTitleView.setText(post.title);
157+
mBodyView.setText(post.body);
158+
}
159+
}
160+
161+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<android.support.v4.widget.SwipeRefreshLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:id="@+id/swipe_refresh_layout"
6+
android:layout_width="match_parent"
7+
android:layout_height="match_parent"
8+
tools:context="com.firebase.uidemo.database.realtime.FirebaseDbPagingActivity">
9+
10+
<android.support.v7.widget.RecyclerView
11+
android:id="@+id/paging_recycler"
12+
android:layout_width="match_parent"
13+
android:layout_height="match_parent"
14+
android:layout_below="@+id/paging_loading"
15+
android:clipToPadding="false"
16+
android:paddingLeft="16dp"
17+
android:paddingTop="8dp"
18+
android:paddingRight="16dp"
19+
tools:listitem="@layout/item_post" />
20+
21+
</android.support.v4.widget.SwipeRefreshLayout>

app/src/main/res/layout/item_post.xml

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:app="http://schemas.android.com/apk/res-auto"
4+
android:layout_width="match_parent"
5+
android:orientation="vertical"
6+
android:layout_height="wrap_content">
7+
8+
<android.support.v7.widget.CardView
9+
android:layout_width="match_parent"
10+
android:layout_height="wrap_content"
11+
android:layout_marginLeft="4dp"
12+
android:layout_marginTop="2dp"
13+
android:layout_marginRight="4dp"
14+
android:layout_marginBottom="2dp"
15+
android:clickable="true"
16+
android:foreground="?android:selectableItemBackground"
17+
app:cardElevation="2dp"
18+
android:focusable="true">
19+
20+
<LinearLayout
21+
android:layout_width="match_parent"
22+
android:layout_height="wrap_content"
23+
android:orientation="vertical"
24+
android:padding="8dp">
25+
26+
<TextView
27+
android:id="@+id/textViewTitle"
28+
android:layout_width="wrap_content"
29+
android:layout_height="wrap_content"
30+
android:text="@string/post_text_title"
31+
android:textColor="#000000"
32+
android:textSize="18sp"
33+
android:textStyle="bold" />
34+
35+
<TextView
36+
android:id="@+id/textViewBody"
37+
android:layout_width="wrap_content"
38+
android:layout_height="wrap_content"
39+
android:layout_margin="4dp"
40+
android:text="@string/post_text_body"
41+
android:textColor="#000000"
42+
android:textSize="15sp" />
43+
</LinearLayout>
44+
</android.support.v7.widget.CardView>
45+
46+
47+
</LinearLayout>

app/src/main/res/values/strings.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
<string name="title_firestore_activity">Cloud Firestore Demo</string>
77
<string name="title_firestore_paging_activity">Cloud Firestore Paging Demo</string>
88
<string name="title_realtime_database_activity">Real-time database demo</string>
9+
<string name="title_paging_database_activity">Paging database demo</string>
910
<string name="title_storage_activity">Storage Image Demo</string>
1011

1112
<string name="desc_auth">Demonstrates the Firebase Auth UI flow, with customization options.</string>
1213
<string name="desc_anonymous_upgrade">Demonstrates upgrading an anonymous account using FirebaseUI.</string>
1314
<string name="desc_firestore">Demonstrates using a FirestoreRecyclerAdapter to load data from Cloud Firestore into a RecyclerView for a basic chat app.</string>
1415
<string name="desc_firestore_paging">Demonstrates using a FirestorePagingAdapter to load/infinite scroll paged data from Cloud Firestore.</string>
1516
<string name="desc_realtime_database">Demonstrates using a FirebaseRecyclerAdapter to load data from Firebase Database into a RecyclerView for a basic chat app.</string>
17+
<string name="desc_paging_database">Demonstrates using a FirebaseRecyclerPagingAdapter to load/infinite scroll paged data from Firebase Database.</string>
1618
<string name="desc_storage">Demonstrates displaying an image from Cloud Storage using Glide.</string>
1719

1820
<!-- Auth UI -->
@@ -118,6 +120,8 @@
118120
<string name="start_chatting">No messages. Start chatting at the bottom!</string>
119121
<string name="signing_in">Signing in…</string>
120122
<string name="signed_in">Signed In</string>
123+
<string name="post_text_title">Title</string>
124+
<string name="post_text_body">Body</string>
121125
<string name="anonymous_auth_failed_msg">
122126
Anonymous authentication failed, various components of the demo will not work.
123127
Make sure your device is online and that Anonymous Auth is configured in your Firebase project
@@ -126,4 +130,5 @@
126130

127131
<string name="menu_add_data">Add Data</string>
128132
<string name="hint_message">Say something…</string>
133+
<string name="paging_finished_message">Reached End of List</string>
129134
</resources>

database/build.gradle.kts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,14 @@ android {
44
defaultConfig {
55
testInstrumentationRunner = "android.support.test.runner.AndroidJUnitRunner"
66
}
7+
8+
buildTypes {
9+
named("release").configure {
10+
postprocessing {
11+
consumerProguardFiles("proguard-rules.pro")
12+
}
13+
}
14+
}
715
}
816

917
dependencies {
@@ -12,6 +20,8 @@ dependencies {
1220

1321
api(Config.Libs.Support.v4)
1422
api(Config.Libs.Support.recyclerView)
23+
24+
compileOnly(Config.Libs.Arch.paging)
1525
annotationProcessor(Config.Libs.Arch.compiler)
1626

1727
androidTestImplementation(Config.Libs.Test.junit)

database/proguard-rules.pro

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
-dontwarn com.firebase.ui.database.paging.**

0 commit comments

Comments
 (0)