Skip to content

Commit d6afe1a

Browse files
author
Zachary Siegel
committed
Adding a new RetainedFragment example
1 parent 8e242a4 commit d6afe1a

File tree

4 files changed

+185
-1
lines changed

4 files changed

+185
-1
lines changed

rxjava-contrib/rxjava-android-samples/samples/src/main/AndroidManifest.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,16 @@
99
android:theme="@style/AppTheme"
1010
android:label="@string/app_name">
1111
<activity
12-
android:name=".RetainedFragmentActivity">
12+
android:name=".RetainedFragmentActivityV2">
13+
14+
<intent-filter>
15+
<category android:name="android.intent.category.LAUNCHER"/>
16+
<category android:name="android.intent.category.DEFAULT"/>
17+
<action android:name="android.intent.action.MAIN"/>
18+
</intent-filter>
19+
</activity>
20+
<activity
21+
android:name=".RetainedFragmentActivity">
1322

1423
<intent-filter>
1524
<category android:name="android.intent.category.LAUNCHER"/>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
package com.netflix.rxjava.android.samples;
2+
3+
import android.app.Activity;
4+
import android.app.Fragment;
5+
import android.os.Bundle;
6+
import android.view.LayoutInflater;
7+
import android.view.View;
8+
import android.view.ViewGroup;
9+
import android.view.Window;
10+
import android.widget.Button;
11+
import android.widget.TextView;
12+
import org.json.JSONException;
13+
import org.json.JSONObject;
14+
import rx.Observable;
15+
import rx.Subscription;
16+
import rx.android.schedulers.AndroidSchedulers;
17+
import rx.functions.Action1;
18+
import rx.functions.Func1;
19+
import rx.subscriptions.Subscriptions;
20+
21+
/**
22+
* A retained fragment whose goals are below
23+
*
24+
* 1) gracefully handle rotation - not losing any data
25+
* 2) gracefully handle the user moving in and out of the app
26+
* 3) use a button or trigger of some sort to start the observable, something more in line with typical use
27+
* 4) ensure that the callbacks are not called if the user moves away from the fragment
28+
*
29+
* @author zsiegel ([email protected])
30+
*/
31+
public class RetainedFragmentActivityV2 extends Activity {
32+
33+
@Override
34+
protected void onCreate(Bundle savedInstanceState) {
35+
super.onCreate(savedInstanceState);
36+
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
37+
setTitle("Fake API call V2");
38+
setContentView(R.layout.retained_fragment_activity_v2);
39+
}
40+
41+
@SuppressWarnings("ConstantConditions")
42+
public static class RetainedFragmentV2 extends Fragment {
43+
44+
private Observable<String> observable;
45+
private Subscription subscription = Subscriptions.empty();
46+
private Button startButton;
47+
private boolean progressVisiblity;
48+
49+
// in a production app, you don't want to have JSON parser code in your fragment,
50+
// but we'll simplify a little here
51+
private static final Func1<String, String> PARSE_JSON = new Func1<String, String>() {
52+
@Override
53+
public String call(String json) {
54+
try {
55+
JSONObject jsonObject = new JSONObject(json);
56+
return String.valueOf(jsonObject.getInt("result"));
57+
} catch (JSONException e) {
58+
throw new RuntimeException(e);
59+
}
60+
}
61+
};
62+
63+
public RetainedFragmentV2() {
64+
setRetainInstance(true);
65+
}
66+
67+
/**
68+
* We un-subscribe whenever we are paused
69+
*/
70+
@Override
71+
public void onPause() {
72+
subscription.unsubscribe();
73+
super.onPause();
74+
}
75+
76+
/**
77+
* We re-subscribe whenever we are resumed
78+
*/
79+
@Override
80+
public void onResume() {
81+
super.onResume();
82+
subscribe();
83+
}
84+
85+
@Override
86+
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
87+
return inflater.inflate(R.layout.retained_fragment_v2, container, false);
88+
}
89+
90+
@Override
91+
public void onViewCreated(final View view, Bundle savedInstanceState) {
92+
super.onViewCreated(view, savedInstanceState);
93+
94+
final TextView textView = (TextView)getView().findViewById(android.R.id.text1);
95+
96+
startButton = (Button) view.findViewById(R.id.button);
97+
startButton.setOnClickListener(new View.OnClickListener() {
98+
@Override
99+
public void onClick(View v) {
100+
textView.setText("");
101+
start();
102+
startButton.setEnabled(false);
103+
}
104+
});
105+
}
106+
107+
private void start() {
108+
109+
progressVisiblity = true;
110+
111+
observable = SampleObservables
112+
.fakeApiCall(5000)
113+
.map(PARSE_JSON)
114+
.observeOn(AndroidSchedulers.mainThread())
115+
.cache();
116+
117+
subscribe();
118+
}
119+
120+
/**
121+
* We subscribe/re-subscribe here
122+
*/
123+
private void subscribe() {
124+
if (observable != null) {
125+
126+
getActivity().setProgressBarIndeterminateVisibility(progressVisiblity);
127+
128+
final TextView textView = (TextView)getView().findViewById(android.R.id.text1);
129+
130+
subscription = observable.subscribe(new Action1<String>() {
131+
@Override
132+
public void call(String result) {
133+
textView.setText(result);
134+
progressVisiblity = false;
135+
getActivity().setProgressBarIndeterminateVisibility(progressVisiblity);
136+
startButton.setEnabled(true);
137+
}
138+
});
139+
}
140+
}
141+
}
142+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
2+
xmlns:tools="http://schemas.android.com/tools"
3+
android:layout_width="match_parent"
4+
android:layout_height="match_parent"
5+
tools:context="com.netflix.rxjava.android.samples.RetainedFragmentActivity">
6+
7+
<fragment
8+
android:tag="retained_fragment_v2"
9+
android:layout_width="match_parent"
10+
android:layout_height="match_parent"
11+
android:name="com.netflix.rxjava.android.samples.RetainedFragmentActivityV2$RetainedFragmentV2"
12+
tools:layout="@layout/retained_fragment" />
13+
14+
</RelativeLayout>
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+
3+
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
4+
android:layout_width="match_parent"
5+
android:layout_height="match_parent">
6+
7+
<TextView
8+
android:id="@android:id/text1"
9+
android:layout_centerInParent="true"
10+
android:layout_width="wrap_content"
11+
android:layout_height="wrap_content" />
12+
13+
<Button
14+
android:id="@+id/button"
15+
android:text="start!"
16+
android:layout_width="wrap_content"
17+
android:layout_height="wrap_content"/>
18+
19+
</LinearLayout>

0 commit comments

Comments
 (0)