Skip to content

Commit 7414896

Browse files
Merge pull request #1009 from zsiegel/update-android-sample
Android - Adding a new RetainedFragment example
2 parents 223ea4c + bb46e03 commit 7414896

File tree

4 files changed

+193
-1
lines changed

4 files changed

+193
-1
lines changed

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

+10-1
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=".UIBindingActivity">
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,150 @@
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+
* Problem:
23+
* You have a data source (where that data is potentially expensive to obtain), and you want to
24+
* emit this data into a fragment. However, you want to gracefully deal with rotation changes and
25+
* not lose any data already emitted.
26+
* <p/>
27+
* You also want your UI to update accordingly to the data being emitted.
28+
*
29+
* @author zsiegel ([email protected])
30+
*/
31+
public class UIBindingActivity extends Activity {
32+
33+
@Override
34+
protected void onCreate(Bundle savedInstanceState) {
35+
super.onCreate(savedInstanceState);
36+
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
37+
setTitle("UIBinding");
38+
setContentView(R.layout.ui_binding_activity);
39+
}
40+
41+
@SuppressWarnings("ConstantConditions")
42+
public static class RetainedBindingFragment extends Fragment {
43+
44+
private Button startButton;
45+
46+
private Observable<String> request;
47+
private Subscription requestSubscription = Subscriptions.empty();
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 RetainedBindingFragment() {
64+
setRetainInstance(true);
65+
}
66+
67+
/**
68+
* We un-subscribe whenever we are paused
69+
*/
70+
@Override
71+
public void onPause() {
72+
requestSubscription.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+
}
103+
});
104+
}
105+
106+
private void start() {
107+
108+
request = SampleObservables
109+
.fakeApiCall(5000)
110+
.map(PARSE_JSON)
111+
.observeOn(AndroidSchedulers.mainThread())
112+
.cache();
113+
114+
subscribe();
115+
}
116+
117+
/**
118+
* We subscribe/re-subscribe here
119+
*/
120+
private void subscribe() {
121+
if (request != null) {
122+
123+
final TextView textView = (TextView) getView().findViewById(android.R.id.text1);
124+
125+
requestSubscription = request.map(new Func1<String, Boolean>() {
126+
127+
//Consume the data that comes back and then signal that we are done
128+
@Override
129+
public Boolean call(String s) {
130+
textView.setText(s);
131+
return true;
132+
}
133+
}).startWith(false) //Before we receive data our request is not complete
134+
.subscribe(new Action1<Boolean>() {
135+
136+
//We update the UI based on the state of the request
137+
@Override
138+
public void call(Boolean completed) {
139+
setRequestInProgress(completed);
140+
}
141+
});
142+
}
143+
}
144+
145+
private void setRequestInProgress(boolean completed) {
146+
getActivity().setProgressBarIndeterminateVisibility(!completed);
147+
startButton.setEnabled(completed);
148+
}
149+
}
150+
}
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>
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.UIBindingActivity$RetainedBindingFragment"
12+
tools:layout="@layout/retained_fragment" />
13+
14+
</RelativeLayout>

0 commit comments

Comments
 (0)