Skip to content

Commit e16784d

Browse files
SUPERCILEXsamtstern
authored andcommitted
Add support for Android Architecture Components (#827)
1 parent 382ee81 commit e16784d

File tree

9 files changed

+212
-36
lines changed

9 files changed

+212
-36
lines changed

app/src/main/java/com/firebase/uidemo/database/ChatActivity.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
package com.firebase.uidemo.database;
1616

17+
import android.arch.lifecycle.LifecycleRegistry;
18+
import android.arch.lifecycle.LifecycleRegistryOwner;
1719
import android.os.Bundle;
1820
import android.support.annotation.NonNull;
1921
import android.support.v7.app.AppCompatActivity;
@@ -37,17 +39,21 @@
3739
import com.google.firebase.database.FirebaseDatabase;
3840
import com.google.firebase.database.Query;
3941

40-
public class ChatActivity extends AppCompatActivity implements FirebaseAuth.AuthStateListener, View.OnClickListener {
42+
public class ChatActivity extends AppCompatActivity
43+
implements FirebaseAuth.AuthStateListener, View.OnClickListener, LifecycleRegistryOwner {
4144
private static final String TAG = "RecyclerViewDemo";
4245

46+
// TODO remove once arch components are merged into support lib
47+
private final LifecycleRegistry mRegistry = new LifecycleRegistry(this);
48+
4349
private FirebaseAuth mAuth;
4450
protected DatabaseReference mChatRef;
4551
private Button mSendButton;
4652
protected EditText mMessageEdit;
4753

4854
private RecyclerView mMessages;
4955
private LinearLayoutManager mManager;
50-
protected FirebaseRecyclerAdapter<Chat, ChatHolder> mAdapter;
56+
private FirebaseRecyclerAdapter<Chat, ChatHolder> mAdapter;
5157
protected TextView mEmptyListMessage;
5258

5359
@Override
@@ -70,8 +76,10 @@ protected void onCreate(Bundle savedInstanceState) {
7076
mManager.setReverseLayout(false);
7177

7278
mMessages = (RecyclerView) findViewById(R.id.messagesList);
73-
mMessages.setHasFixedSize(false);
79+
mMessages.setHasFixedSize(true);
7480
mMessages.setLayoutManager(mManager);
81+
82+
if (isSignedIn()) { attachRecyclerViewAdapter(); }
7583
}
7684

7785
@Override
@@ -81,19 +89,7 @@ public void onStart() {
8189
// Default Database rules do not allow unauthenticated reads, so we need to
8290
// sign in before attaching the RecyclerView adapter otherwise the Adapter will
8391
// not be able to read any data from the Database.
84-
if (isSignedIn()) {
85-
attachRecyclerViewAdapter();
86-
} else {
87-
signInAnonymously();
88-
}
89-
}
90-
91-
@Override
92-
public void onStop() {
93-
super.onStop();
94-
if (mAdapter != null) {
95-
mAdapter.cleanup();
96-
}
92+
if (!isSignedIn()) { signInAnonymously(); }
9793
}
9894

9995
@Override
@@ -147,7 +143,8 @@ protected FirebaseRecyclerAdapter<Chat, ChatHolder> getAdapter() {
147143
Chat.class,
148144
R.layout.message,
149145
ChatHolder.class,
150-
lastFifty) {
146+
lastFifty,
147+
this) {
151148
@Override
152149
public void populateViewHolder(ChatHolder holder, Chat chat, int position) {
153150
holder.bind(chat);
@@ -182,4 +179,9 @@ private void updateUI() {
182179
mSendButton.setEnabled(isSignedIn());
183180
mMessageEdit.setEnabled(isSignedIn());
184181
}
182+
183+
@Override
184+
public LifecycleRegistry getLifecycle() {
185+
return mRegistry;
186+
}
185187
}

app/src/main/java/com/firebase/uidemo/database/ChatIndexActivity.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ protected FirebaseRecyclerAdapter<Chat, ChatHolder> getAdapter() {
3939
R.layout.message,
4040
ChatHolder.class,
4141
mChatIndicesRef.limitToLast(50),
42-
mChatRef) {
42+
mChatRef,
43+
this) {
4344
@Override
4445
public void populateViewHolder(ChatHolder holder, Chat chat, int position) {
4546
holder.bind(chat);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<android.support.v7.widget.RecyclerView
1717
android:id="@+id/messagesList"
1818
android:layout_width="match_parent"
19-
android:layout_height="wrap_content"
19+
android:layout_height="match_parent"
2020
android:layout_alignParentStart="true"
2121
android:layout_alignParentLeft="true"
2222
android:layout_alignParentTop="true"

database/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ dependencies {
2727
// Needed to override play services
2828
compile "com.android.support:support-v4:$supportLibraryVersion"
2929

30+
compile 'android.arch.lifecycle:runtime:1.0.0-alpha5'
31+
compile 'android.arch.lifecycle:extensions:1.0.0-alpha5'
32+
annotationProcessor 'android.arch.lifecycle:compiler:1.0.0-alpha5'
33+
3034
compile "com.google.firebase:firebase-database:$firebaseVersion"
3135

3236
androidTestCompile 'junit:junit:4.12'

database/src/main/java/com/firebase/ui/database/FirebaseAdapter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
package com.firebase.ui.database;
22

3+
import android.arch.lifecycle.LifecycleObserver;
34
import android.support.annotation.RestrictTo;
45

56
import com.google.firebase.database.DatabaseReference;
67

78
@RestrictTo(RestrictTo.Scope.LIBRARY_GROUP)
8-
interface FirebaseAdapter<T> extends ChangeEventListener {
9+
interface FirebaseAdapter<T> extends ChangeEventListener, LifecycleObserver {
910
/**
1011
* If you need to do some setup before the adapter starts listening for change events in the
1112
* database, do so it here and then call {@code super.startListening()}.

database/src/main/java/com/firebase/ui/database/FirebaseIndexListAdapter.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.firebase.ui.database;
22

3-
import android.app.Activity;
3+
import android.arch.lifecycle.LifecycleOwner;
4+
import android.content.Context;
45
import android.support.annotation.LayoutRes;
56
import android.widget.ListView;
67

@@ -18,25 +19,51 @@ public abstract class FirebaseIndexListAdapter<T> extends FirebaseListAdapter<T>
1819
* {@link DatabaseReference}.</b>
1920
* @param dataRef The Firebase location to watch for data changes. Each key key found at {@code
2021
* keyQuery}'s location represents a list item in the {@link ListView}.
21-
* @see FirebaseIndexListAdapter#FirebaseIndexListAdapter(Activity, SnapshotParser, int, Query,
22-
* DatabaseReference)
22+
* @see FirebaseListAdapter#FirebaseListAdapter(Context, ObservableSnapshotArray, int,
23+
* LifecycleOwner)
2324
*/
24-
public FirebaseIndexListAdapter(Activity activity,
25+
public FirebaseIndexListAdapter(Context context,
26+
SnapshotParser<T> parser,
27+
@LayoutRes int modelLayout,
28+
Query keyQuery,
29+
DatabaseReference dataRef,
30+
LifecycleOwner owner) {
31+
super(context, new FirebaseIndexArray<>(keyQuery, dataRef, parser), modelLayout, owner);
32+
}
33+
34+
/**
35+
* @see #FirebaseIndexListAdapter(Context, SnapshotParser, int, Query, DatabaseReference,
36+
* LifecycleOwner)
37+
*/
38+
public FirebaseIndexListAdapter(Context context,
2539
SnapshotParser<T> parser,
2640
@LayoutRes int modelLayout,
2741
Query keyQuery,
2842
DatabaseReference dataRef) {
29-
super(activity, new FirebaseIndexArray<>(keyQuery, dataRef, parser), modelLayout);
43+
super(context, new FirebaseIndexArray<>(keyQuery, dataRef, parser), modelLayout);
44+
}
45+
46+
/**
47+
* @see #FirebaseIndexListAdapter(Context, SnapshotParser, int, Query, DatabaseReference,
48+
* LifecycleOwner)
49+
*/
50+
public FirebaseIndexListAdapter(Context context,
51+
Class<T> modelClass,
52+
@LayoutRes int modelLayout,
53+
Query keyQuery,
54+
DatabaseReference dataRef,
55+
LifecycleOwner owner) {
56+
this(context, new ClassSnapshotParser<>(modelClass), modelLayout, keyQuery, dataRef, owner);
3057
}
3158

3259
/**
33-
* @see #FirebaseIndexListAdapter(Activity, SnapshotParser, int, Query, DatabaseReference)
60+
* @see #FirebaseIndexListAdapter(Context, SnapshotParser, int, Query, DatabaseReference)
3461
*/
35-
public FirebaseIndexListAdapter(Activity activity,
62+
public FirebaseIndexListAdapter(Context context,
3663
Class<T> modelClass,
3764
@LayoutRes int modelLayout,
3865
Query keyQuery,
3966
DatabaseReference dataRef) {
40-
this(activity, new ClassSnapshotParser<>(modelClass), modelLayout, keyQuery, dataRef);
67+
this(context, new ClassSnapshotParser<>(modelClass), modelLayout, keyQuery, dataRef);
4168
}
4269
}

database/src/main/java/com/firebase/ui/database/FirebaseIndexRecyclerAdapter.java

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.firebase.ui.database;
22

3+
import android.arch.lifecycle.LifecycleOwner;
34
import android.support.annotation.LayoutRes;
45
import android.support.v7.widget.RecyclerView;
56

@@ -18,7 +19,24 @@ public abstract class FirebaseIndexRecyclerAdapter<T, VH extends RecyclerView.Vi
1819
* {@link DatabaseReference}.</b>
1920
* @param dataRef The Firebase location to watch for data changes. Each key key found at {@code
2021
* keyQuery}'s location represents a list item in the {@link RecyclerView}.
21-
* @see FirebaseRecyclerAdapter#FirebaseRecyclerAdapter(ObservableSnapshotArray, int, Class)
22+
* @see FirebaseRecyclerAdapter#FirebaseRecyclerAdapter(ObservableSnapshotArray, int, Class,
23+
* LifecycleOwner)
24+
*/
25+
public FirebaseIndexRecyclerAdapter(SnapshotParser<T> parser,
26+
@LayoutRes int modelLayout,
27+
Class<VH> viewHolderClass,
28+
Query keyQuery,
29+
DatabaseReference dataRef,
30+
LifecycleOwner owner) {
31+
super(new FirebaseIndexArray<>(keyQuery, dataRef, parser),
32+
modelLayout,
33+
viewHolderClass,
34+
owner);
35+
}
36+
37+
/**
38+
* @see #FirebaseIndexRecyclerAdapter(SnapshotParser, int, Class, Query, DatabaseReference,
39+
* LifecycleOwner)
2240
*/
2341
public FirebaseIndexRecyclerAdapter(SnapshotParser<T> parser,
2442
@LayoutRes int modelLayout,
@@ -28,6 +46,24 @@ public FirebaseIndexRecyclerAdapter(SnapshotParser<T> parser,
2846
super(new FirebaseIndexArray<>(keyQuery, dataRef, parser), modelLayout, viewHolderClass);
2947
}
3048

49+
/**
50+
* @see #FirebaseIndexRecyclerAdapter(SnapshotParser, int, Class, Query, DatabaseReference,
51+
* LifecycleOwner)
52+
*/
53+
public FirebaseIndexRecyclerAdapter(Class<T> modelClass,
54+
@LayoutRes int modelLayout,
55+
Class<VH> viewHolderClass,
56+
Query keyQuery,
57+
DatabaseReference dataRef,
58+
LifecycleOwner owner) {
59+
this(new ClassSnapshotParser<>(modelClass),
60+
modelLayout,
61+
viewHolderClass,
62+
keyQuery,
63+
dataRef,
64+
owner);
65+
}
66+
3167
/**
3268
* @see #FirebaseIndexRecyclerAdapter(SnapshotParser, int, Class, Query, DatabaseReference)
3369
*/
@@ -37,9 +73,9 @@ public FirebaseIndexRecyclerAdapter(Class<T> modelClass,
3773
Query keyQuery,
3874
DatabaseReference dataRef) {
3975
this(new ClassSnapshotParser<>(modelClass),
40-
modelLayout,
41-
viewHolderClass,
42-
keyQuery,
43-
dataRef);
76+
modelLayout,
77+
viewHolderClass,
78+
keyQuery,
79+
dataRef);
4480
}
4581
}

database/src/main/java/com/firebase/ui/database/FirebaseListAdapter.java

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
package com.firebase.ui.database;
22

33
import android.app.Activity;
4+
import android.arch.lifecycle.Lifecycle;
5+
import android.arch.lifecycle.LifecycleOwner;
6+
import android.arch.lifecycle.OnLifecycleEvent;
47
import android.content.Context;
58
import android.support.annotation.LayoutRes;
9+
import android.support.v4.app.FragmentActivity;
610
import android.util.Log;
711
import android.view.LayoutInflater;
812
import android.view.View;
@@ -39,14 +43,28 @@ public abstract class FirebaseListAdapter<T> extends BaseAdapter implements Fire
3943
* @param modelLayout This is the layout used to represent a single list item. You will be
4044
* responsible for populating an instance of the corresponding view with the
4145
* data from an instance of modelClass.
46+
* @param owner the lifecycle owner used to automatically listen and cleanup after {@link
47+
* FragmentActivity#onStart()} and {@link FragmentActivity#onStop()} events
48+
* reflectively.
4249
*/
4350
public FirebaseListAdapter(Context context,
4451
ObservableSnapshotArray<T> snapshots,
45-
@LayoutRes int modelLayout) {
52+
@LayoutRes int modelLayout,
53+
LifecycleOwner owner) {
4654
mContext = context;
4755
mSnapshots = snapshots;
4856
mLayout = modelLayout;
4957

58+
if (owner != null) { owner.getLifecycle().addObserver(this); }
59+
}
60+
61+
/**
62+
* @see #FirebaseListAdapter(Context, ObservableSnapshotArray, int, LifecycleOwner)
63+
*/
64+
public FirebaseListAdapter(Context context,
65+
ObservableSnapshotArray<T> snapshots,
66+
@LayoutRes int modelLayout) {
67+
this(context, snapshots, modelLayout, null);
5068
startListening();
5169
}
5270

@@ -65,6 +83,18 @@ public FirebaseListAdapter(Context context,
6583
this(context, new FirebaseArray<>(query, parser), modelLayout);
6684
}
6785

86+
/**
87+
* @see #FirebaseListAdapter(Context, SnapshotParser, int, Query)
88+
* @see #FirebaseListAdapter(Context, ObservableSnapshotArray, int, LifecycleOwner)
89+
*/
90+
public FirebaseListAdapter(Context context,
91+
SnapshotParser<T> parser,
92+
@LayoutRes int modelLayout,
93+
Query query,
94+
LifecycleOwner owner) {
95+
this(context, new FirebaseArray<>(query, parser), modelLayout, owner);
96+
}
97+
6898
/**
6999
* @see #FirebaseListAdapter(Context, SnapshotParser, int, Query)
70100
*/
@@ -75,7 +105,19 @@ public FirebaseListAdapter(Context context,
75105
this(context, new ClassSnapshotParser<>(modelClass), modelLayout, query);
76106
}
77107

108+
/**
109+
* @see #FirebaseListAdapter(Context, SnapshotParser, int, Query, LifecycleOwner)
110+
*/
111+
public FirebaseListAdapter(Context context,
112+
Class<T> modelClass,
113+
@LayoutRes int modelLayout,
114+
Query query,
115+
LifecycleOwner owner) {
116+
this(context, new ClassSnapshotParser<>(modelClass), modelLayout, query, owner);
117+
}
118+
78119
@Override
120+
@OnLifecycleEvent(Lifecycle.Event.ON_START)
79121
public void startListening() {
80122
if (!mSnapshots.isListening(this)) {
81123
mSnapshots.addChangeEventListener(this);
@@ -87,6 +129,16 @@ public void cleanup() {
87129
mSnapshots.removeChangeEventListener(this);
88130
}
89131

132+
@SuppressWarnings("unused")
133+
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
134+
void cleanup(LifecycleOwner source, Lifecycle.Event event) {
135+
if (event == Lifecycle.Event.ON_STOP) {
136+
cleanup();
137+
} else if (event == Lifecycle.Event.ON_DESTROY) {
138+
source.getLifecycle().removeObserver(this);
139+
}
140+
}
141+
90142
@Override
91143
public void onChildChanged(ChangeEventListener.EventType type,
92144
DataSnapshot snapshot,

0 commit comments

Comments
 (0)