Skip to content

Commit 4d68a56

Browse files
committed
Separate demo
Change-Id: I3b4970fc36dfbbae6045e796577d67e10f015fde
1 parent 75240b7 commit 4d68a56

File tree

9 files changed

+304
-81
lines changed

9 files changed

+304
-81
lines changed

app/src/main/AndroidManifest.xml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
<?xml version="1.0" encoding="utf-8"?>
2-
<manifest
3-
xmlns:android="http://schemas.android.com/apk/res/android"
4-
xmlns:tools="http://schemas.android.com/tools"
5-
package="com.firebase.uidemo">
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.firebase.uidemo">
65

76
<uses-permission android:name="android.permission.INTERNET" />
87
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
@@ -17,7 +16,6 @@
1716
android:supportsRtl="true"
1817
android:theme="@style/AppTheme"
1918
tools:ignore="GoogleAppIndexingWarning">
20-
2119
<activity android:name=".ChooserActivity">
2220
<intent-filter>
2321
<action android:name="android.intent.action.MAIN" />
@@ -43,6 +41,11 @@
4341
android:name=".database.firestore.FirestoreChatActivity"
4442
android:label="@string/title_firestore_activity" />
4543

44+
<!-- Firestore paging demo -->
45+
<activity
46+
android:name=".database.firestore.FirestorePagingActivity"
47+
android:label="@string/title_firestore_paging_activity" />
48+
4649
<!-- Realtime database demo -->
4750
<activity
4851
android:name=".database.realtime.RealtimeDbChatActivity"
@@ -55,7 +58,6 @@
5558
<activity
5659
android:name=".storage.ImageActivity"
5760
android:label="@string/title_storage_activity" />
58-
5961
</application>
6062

6163
</manifest>

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
import com.firebase.uidemo.auth.AuthUiActivity;
2929
import com.firebase.uidemo.database.firestore.FirestoreChatActivity;
30+
import com.firebase.uidemo.database.firestore.FirestorePagingActivity;
3031
import com.firebase.uidemo.database.realtime.RealtimeDbChatActivity;
3132
import com.firebase.uidemo.storage.ImageActivity;
3233

@@ -52,20 +53,23 @@ private static class ActivityChooserAdapter extends RecyclerView.Adapter<Activit
5253
private static final Class[] CLASSES = new Class[]{
5354
AuthUiActivity.class,
5455
FirestoreChatActivity.class,
56+
FirestorePagingActivity.class,
5557
RealtimeDbChatActivity.class,
5658
ImageActivity.class,
5759
};
5860

5961
private static final int[] DESCRIPTION_NAMES = new int[]{
6062
R.string.title_auth_activity,
6163
R.string.title_firestore_activity,
64+
R.string.title_firestore_paging_activity,
6265
R.string.title_realtime_database_activity,
6366
R.string.title_storage_activity
6467
};
6568

6669
private static final int[] DESCRIPTION_IDS = new int[]{
6770
R.string.desc_auth,
6871
R.string.desc_firestore,
72+
R.string.desc_firestore_paging,
6973
R.string.desc_realtime_database,
7074
R.string.desc_storage
7175
};

app/src/main/java/com/firebase/uidemo/database/firestore/FirestoreChatActivity.java

Lines changed: 24 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,16 @@
77
import android.support.v7.widget.RecyclerView;
88
import android.util.Log;
99
import android.view.LayoutInflater;
10+
import android.view.View;
1011
import android.view.ViewGroup;
1112
import android.widget.Button;
1213
import android.widget.EditText;
1314
import android.widget.TextView;
1415
import android.widget.Toast;
1516

1617
import com.firebase.ui.auth.util.ui.ImeHelper;
17-
import com.firebase.ui.firestore.ClassSnapshotParser;
18-
import com.firebase.ui.firestore.FirestoreInfiniteScrollListener;
19-
import com.firebase.ui.firestore.FirestorePagingAdapter;
20-
import com.firebase.ui.firestore.FirestorePagingOptions;
2118
import com.firebase.ui.firestore.FirestoreRecyclerAdapter;
19+
import com.firebase.ui.firestore.FirestoreRecyclerOptions;
2220
import com.firebase.uidemo.R;
2321
import com.firebase.uidemo.database.ChatHolder;
2422
import com.firebase.uidemo.util.SignInResultNotifier;
@@ -49,8 +47,6 @@ public class FirestoreChatActivity extends AppCompatActivity
4947
/** Get the last 50 chat messages ordered by timestamp . */
5048
private static final Query sChatQuery = sChatCollection.orderBy("timestamp").limit(50);
5149

52-
private LinearLayoutManager mManager;
53-
5450
static {
5551
FirebaseFirestore.setLoggingEnabled(true);
5652
}
@@ -73,9 +69,8 @@ protected void onCreate(Bundle savedInstanceState) {
7369
setContentView(R.layout.activity_chat);
7470
ButterKnife.bind(this);
7571

76-
mManager = new LinearLayoutManager(this);
7772
mRecyclerView.setHasFixedSize(true);
78-
mRecyclerView.setLayoutManager(mManager);
73+
mRecyclerView.setLayoutManager(new LinearLayoutManager(this));
7974

8075
ImeHelper.setImeOnDoneListener(mMessageEdit, new ImeHelper.DonePressedListener() {
8176
@Override
@@ -88,6 +83,7 @@ public void onDonePressed() {
8883
@Override
8984
public void onStart() {
9085
super.onStart();
86+
if (isSignedIn()) { attachRecyclerViewAdapter(); }
9187
FirebaseAuth.getInstance().addAuthStateListener(this);
9288
}
9389

@@ -115,20 +111,15 @@ private boolean isSignedIn() {
115111
}
116112

117113
private void attachRecyclerViewAdapter() {
118-
final FirestorePagingAdapter adapter = newAdapter();
114+
final RecyclerView.Adapter adapter = newAdapter();
119115

120116
// Scroll to bottom on new messages
121-
// TODO
122-
// adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
123-
// @Override
124-
// public void onItemRangeInserted(int positionStart, int itemCount) {
125-
// mRecyclerView.smoothScrollToPosition(adapter.getItemCount());
126-
// }
127-
// });
128-
129-
// Scroll listener for infinite
130-
mRecyclerView.addOnScrollListener(
131-
new FirestoreInfiniteScrollListener(mManager, adapter));
117+
adapter.registerAdapterDataObserver(new RecyclerView.AdapterDataObserver() {
118+
@Override
119+
public void onItemRangeInserted(int positionStart, int itemCount) {
120+
mRecyclerView.smoothScrollToPosition(adapter.getItemCount());
121+
}
122+
});
132123

133124
mRecyclerView.setAdapter(adapter);
134125
}
@@ -143,17 +134,14 @@ public void onSendClick() {
143134
mMessageEdit.setText("");
144135
}
145136

146-
protected FirestorePagingAdapter newAdapter() {
147-
FirestorePagingOptions options = new FirestorePagingOptions.Builder()
148-
.setLoadTriggerDistance(7)
149-
.setMaxPages(3)
150-
.build();
151-
152-
return new FirestorePagingAdapter<Chat, ChatHolder>(
153-
new ClassSnapshotParser<>(Chat.class),
154-
sChatCollection.orderBy("timestamp", Query.Direction.ASCENDING),
155-
options) {
137+
protected RecyclerView.Adapter newAdapter() {
138+
FirestoreRecyclerOptions<Chat> options =
139+
new FirestoreRecyclerOptions.Builder<Chat>()
140+
.setQuery(sChatQuery, Chat.class)
141+
.setLifecycleOwner(this)
142+
.build();
156143

144+
return new FirestoreRecyclerAdapter<Chat, ChatHolder>(options) {
157145
@Override
158146
public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
159147
return new ChatHolder(LayoutInflater.from(parent.getContext())
@@ -164,6 +152,12 @@ public ChatHolder onCreateViewHolder(ViewGroup parent, int viewType) {
164152
protected void onBindViewHolder(@NonNull ChatHolder holder, int position, @NonNull Chat model) {
165153
holder.bind(model);
166154
}
155+
156+
@Override
157+
public void onDataChanged() {
158+
// If there are no chat messages, show a view that invites the user to add a message.
159+
mEmptyListMessage.setVisibility(getItemCount() == 0 ? View.VISIBLE : View.GONE);
160+
}
167161
};
168162
}
169163

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
package com.firebase.uidemo.database.firestore;
2+
3+
import android.os.Bundle;
4+
import android.support.v7.app.AppCompatActivity;
5+
import android.support.v7.widget.LinearLayoutManager;
6+
import android.support.v7.widget.RecyclerView;
7+
import android.view.LayoutInflater;
8+
import android.view.View;
9+
import android.view.ViewGroup;
10+
import android.widget.TextView;
11+
12+
import com.firebase.ui.firestore.FirestoreInfiniteScrollListener;
13+
import com.firebase.ui.firestore.FirestorePagingAdapter;
14+
import com.firebase.ui.firestore.FirestorePagingOptions;
15+
import com.firebase.uidemo.R;
16+
import com.google.android.gms.tasks.Task;
17+
import com.google.firebase.firestore.CollectionReference;
18+
import com.google.firebase.firestore.FirebaseFirestore;
19+
import com.google.firebase.firestore.Query;
20+
import com.google.firebase.firestore.WriteBatch;
21+
22+
import java.util.Locale;
23+
24+
import butterknife.BindView;
25+
import butterknife.ButterKnife;
26+
27+
public class FirestorePagingActivity extends AppCompatActivity {
28+
29+
@BindView(R.id.paging_recycler)
30+
RecyclerView mRecycler;
31+
32+
@Override
33+
protected void onCreate(Bundle savedInstanceState) {
34+
super.onCreate(savedInstanceState);
35+
setContentView(R.layout.activity_firestore_paging);
36+
ButterKnife.bind(this);
37+
38+
setUpAdapter();
39+
}
40+
41+
private void setUpAdapter() {
42+
Query baseQuery = FirebaseFirestore.getInstance()
43+
.collection("items")
44+
.orderBy("value", Query.Direction.ASCENDING);
45+
46+
FirestorePagingOptions<Item> options = new FirestorePagingOptions.Builder<Item>()
47+
.setQuery(baseQuery, Item.class)
48+
.setPageSize(10)
49+
.setLoadTriggerDistance(5)
50+
.setMaxPages(3)
51+
.build();
52+
53+
FirestorePagingAdapter<Item, ItemViewHolder> adapter =
54+
new FirestorePagingAdapter<Item, ItemViewHolder>(options) {
55+
@Override
56+
public ItemViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
57+
View view = LayoutInflater.from(parent.getContext())
58+
.inflate(R.layout.item_item, parent, false);
59+
60+
return new ItemViewHolder(view);
61+
}
62+
63+
@Override
64+
protected void onBindViewHolder(ItemViewHolder holder, int position, Item model) {
65+
holder.bind(model);
66+
}
67+
};
68+
69+
LinearLayoutManager manager = new LinearLayoutManager(this);
70+
71+
FirestoreInfiniteScrollListener listener =
72+
new FirestoreInfiniteScrollListener(manager, adapter);
73+
74+
mRecycler.setLayoutManager(manager);
75+
mRecycler.setAdapter(adapter);
76+
mRecycler.addOnScrollListener(listener);
77+
}
78+
79+
// TODO: Bind this to a menu item
80+
public Task<Void> createItems() {
81+
82+
WriteBatch writeBatch = FirebaseFirestore.getInstance().batch();
83+
CollectionReference collRef = FirebaseFirestore.getInstance().collection("items");
84+
85+
for (int i = 0; i < 500; i++) {
86+
String title = "Item " + i;
87+
88+
String id = String.format(Locale.getDefault(), "item_%03d", i);
89+
Item item = new Item(title, i);
90+
91+
writeBatch.set(collRef.document(id), item);
92+
}
93+
94+
return writeBatch.commit();
95+
}
96+
97+
public static class Item {
98+
99+
public String text;
100+
public int value;
101+
102+
public Item() {}
103+
104+
public Item(String text, int value) {
105+
this.text = text;
106+
this.value = value;
107+
}
108+
109+
}
110+
111+
public static class ItemViewHolder extends RecyclerView.ViewHolder {
112+
113+
@BindView(R.id.item_text)
114+
TextView mTextView;
115+
116+
@BindView(R.id.item_value)
117+
TextView mValueView;
118+
119+
ItemViewHolder(View itemView) {
120+
super(itemView);
121+
ButterKnife.bind(this, itemView);
122+
}
123+
124+
void bind(Item item) {
125+
mTextView.setText(item.text);
126+
mValueView.setText(String.valueOf(item.value));
127+
}
128+
}
129+
130+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<RelativeLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:layout_width="match_parent"
6+
android:layout_height="match_parent"
7+
tools:context="com.firebase.uidemo.database.firestore.FirestorePagingActivity">
8+
9+
<android.support.v7.widget.RecyclerView
10+
android:id="@+id/paging_recycler"
11+
android:layout_width="match_parent"
12+
android:layout_height="wrap_content"
13+
tools:listitem="@layout/item_item"
14+
android:paddingLeft="16dp"
15+
android:paddingRight="16dp"
16+
android:paddingTop="8dp"
17+
android:clipToPadding="false" />
18+
19+
</RelativeLayout>

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

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<LinearLayout
3+
xmlns:android="http://schemas.android.com/apk/res/android"
4+
xmlns:tools="http://schemas.android.com/tools"
5+
android:layout_width="match_parent"
6+
android:layout_height="wrap_content"
7+
android:paddingLeft="16dp"
8+
android:paddingRight="16dp"
9+
android:paddingBottom="8dp"
10+
android:paddingTop="8dp"
11+
android:layout_marginBottom="8dp"
12+
android:background="@drawable/ic_chat_message_background"
13+
android:orientation="vertical">
14+
15+
<TextView
16+
android:id="@+id/item_text"
17+
android:layout_width="wrap_content"
18+
android:layout_height="wrap_content"
19+
android:textSize="16sp"
20+
android:textStyle="bold"
21+
tools:text="My Text" />
22+
23+
<TextView
24+
android:id="@+id/item_value"
25+
android:layout_width="wrap_content"
26+
android:layout_height="wrap_content"
27+
android:textSize="12sp"
28+
tools:text="1234" />
29+
30+
</LinearLayout>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
<!-- Chooser -->
55
<string name="title_auth_activity">Auth UI demo</string>
66
<string name="title_firestore_activity">Cloud Firestore Demo</string>
7+
<string name="title_firestore_paging_activity">Cloud Firestore Paging Demo</string>
78
<string name="title_realtime_database_activity">Real-time database demo</string>
89
<string name="title_storage_activity">Storage Image Demo</string>
910

1011
<string name="desc_auth">Demonstrates the Firebase Auth UI flow, with customization options.</string>
1112
<string name="desc_firestore">Demonstrates using a FirestoreRecyclerAdapter to load data from Cloud Firestore into a RecyclerView for a basic chat app.</string>
13+
<string name="desc_firestore_paging">Demonstrates using a FirestorePagingAdapter to load/infinite scroll paging data from Cloud Firestore.</string>
1214
<string name="desc_realtime_database">Demonstrates using a FirebaseRecyclerAdapter to load data from Firebase Database into a RecyclerView for a basic chat app.</string>
1315
<string name="desc_storage">Demonstrates displaying an image from Cloud Storage using Glide.</string>
1416

0 commit comments

Comments
 (0)