Skip to content

Commit b338afa

Browse files
committed
Bring back ViewObservable.input(EditText, boolean) and rename new version to ViewObservable.text
1 parent 0c4dac6 commit b338afa

File tree

4 files changed

+264
-6
lines changed

4 files changed

+264
-6
lines changed

rxjava-contrib/rxjava-android/src/main/java/rx/android/observables/ViewObservable.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,13 @@
1717

1818
import rx.Observable;
1919
import rx.operators.OperatorCompoundButtonInput;
20+
import rx.operators.OperatorEditTextInput;
2021
import rx.operators.OperatorTextViewInput;
2122
import rx.operators.OperatorViewClick;
2223

2324
import android.view.View;
2425
import android.widget.CompoundButton;
26+
import android.widget.EditText;
2527
import android.widget.TextView;
2628

2729
public class ViewObservable {
@@ -30,10 +32,22 @@ public static <T extends View> Observable<T> clicks(final T view, final boolean
3032
return Observable.create(new OperatorViewClick<T>(view, emitInitialValue));
3133
}
3234

33-
public static <T extends TextView> Observable<T> input(final T input, final boolean emitInitialValue) {
35+
public static <T extends TextView> Observable<T> text(final T input) {
36+
return text(input, false);
37+
}
38+
39+
public static <T extends TextView> Observable<T> text(final T input, final boolean emitInitialValue) {
3440
return Observable.create(new OperatorTextViewInput<T>(input, emitInitialValue));
3541
}
3642

43+
/**
44+
* @deprecated Use #text(android.widget.TextView, boolean)} (and map the values) instead.
45+
*/
46+
@Deprecated
47+
public static Observable<String> input(final EditText input, final boolean emitInitialValue) {
48+
return Observable.create(new OperatorEditTextInput(input, emitInitialValue));
49+
}
50+
3751
public static Observable<Boolean> input(final CompoundButton button, final boolean emitInitialValue) {
3852
return Observable.create(new OperatorCompoundButtonInput(button, emitInitialValue));
3953
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/**
2+
* Copyright 2014 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package rx.operators;
17+
18+
import rx.Observable;
19+
import rx.Subscriber;
20+
import rx.Subscription;
21+
import rx.android.observables.Assertions;
22+
import rx.android.subscriptions.AndroidSubscriptions;
23+
import rx.functions.Action0;
24+
import android.text.Editable;
25+
import android.text.TextWatcher;
26+
import android.widget.EditText;
27+
28+
/**
29+
* @deprecated Use {@link rx.operators.OperatorTextViewInput} instead.
30+
*/
31+
@Deprecated
32+
public class OperatorEditTextInput implements Observable.OnSubscribe<String> {
33+
private final EditText input;
34+
private final boolean emitInitialValue;
35+
36+
public OperatorEditTextInput(final EditText input, final boolean emitInitialValue) {
37+
this.input = input;
38+
this.emitInitialValue = emitInitialValue;
39+
}
40+
41+
@Override
42+
public void call(final Subscriber<? super String> observer) {
43+
Assertions.assertUiThread();
44+
final TextWatcher watcher = new SimpleTextWatcher() {
45+
@Override
46+
public void afterTextChanged(final Editable editable) {
47+
observer.onNext(editable.toString());
48+
}
49+
};
50+
51+
final Subscription subscription = AndroidSubscriptions.unsubscribeInUiThread(new Action0() {
52+
@Override
53+
public void call() {
54+
input.removeTextChangedListener(watcher);
55+
}
56+
});
57+
58+
if (emitInitialValue) {
59+
observer.onNext(input.getEditableText().toString());
60+
}
61+
62+
input.addTextChangedListener(watcher);
63+
observer.add(subscription);
64+
}
65+
66+
private static class SimpleTextWatcher implements TextWatcher {
67+
@Override
68+
public void beforeTextChanged(final CharSequence sequence, final int start, final int count, final int after) {
69+
// nothing to do
70+
}
71+
72+
@Override
73+
public void onTextChanged(final CharSequence sequence, final int start, final int before, final int count) {
74+
// nothing to do
75+
}
76+
77+
@Override
78+
public void afterTextChanged(final Editable editable) {
79+
// nothing to do
80+
}
81+
}
82+
}
83+
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
/**
2+
* Copyright 2014 Netflix, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
package rx.android.operators;
17+
18+
import static org.mockito.Matchers.*;
19+
import static org.mockito.Mockito.*;
20+
21+
import android.app.Activity;
22+
import android.widget.EditText;
23+
import org.junit.Test;
24+
import org.junit.runner.RunWith;
25+
import org.mockito.InOrder;
26+
import org.robolectric.Robolectric;
27+
import org.robolectric.RobolectricTestRunner;
28+
import rx.Observable;
29+
import rx.Observer;
30+
import rx.Subscription;
31+
import rx.android.observables.ViewObservable;
32+
import rx.observers.TestObserver;
33+
34+
@RunWith(RobolectricTestRunner.class)
35+
public class OperatorEditTextInputTest {
36+
37+
private static EditText createEditText(final String value) {
38+
final Activity activity = Robolectric.buildActivity(Activity.class).create().get();
39+
final EditText text = new EditText(activity);
40+
41+
if (value != null) {
42+
text.setText(value);
43+
}
44+
45+
return text;
46+
}
47+
48+
@Test
49+
@SuppressWarnings("unchecked")
50+
public void testWithoutInitialValue() {
51+
final EditText input = createEditText("initial");
52+
final Observable<String> observable = ViewObservable.input(input, false);
53+
final Observer<String> observer = mock(Observer.class);
54+
final Subscription subscription = observable.subscribe(new TestObserver<String>(observer));
55+
56+
final InOrder inOrder = inOrder(observer);
57+
58+
inOrder.verify(observer, never()).onNext(anyString());
59+
60+
input.setText("1");
61+
inOrder.verify(observer, times(1)).onNext("1");
62+
63+
input.setText("2");
64+
inOrder.verify(observer, times(1)).onNext("2");
65+
66+
input.setText("3");
67+
inOrder.verify(observer, times(1)).onNext("3");
68+
69+
subscription.unsubscribe();
70+
input.setText("4");
71+
inOrder.verify(observer, never()).onNext(anyString());
72+
73+
inOrder.verify(observer, never()).onError(any(Throwable.class));
74+
inOrder.verify(observer, never()).onCompleted();
75+
}
76+
77+
@Test
78+
@SuppressWarnings("unchecked")
79+
public void testWithInitialValue() {
80+
final EditText input = createEditText("initial");
81+
final Observable<String> observable = ViewObservable.input(input, true);
82+
final Observer<String> observer = mock(Observer.class);
83+
final Subscription subscription = observable.subscribe(new TestObserver<String>(observer));
84+
85+
final InOrder inOrder = inOrder(observer);
86+
87+
inOrder.verify(observer, times(1)).onNext("initial");
88+
89+
input.setText("one");
90+
inOrder.verify(observer, times(1)).onNext("one");
91+
92+
input.setText("two");
93+
inOrder.verify(observer, times(1)).onNext("two");
94+
95+
input.setText("three");
96+
inOrder.verify(observer, times(1)).onNext("three");
97+
98+
subscription.unsubscribe();
99+
input.setText("four");
100+
inOrder.verify(observer, never()).onNext(anyString());
101+
102+
inOrder.verify(observer, never()).onError(any(Throwable.class));
103+
inOrder.verify(observer, never()).onCompleted();
104+
}
105+
106+
@Test
107+
@SuppressWarnings("unchecked")
108+
public void testMultipleSubscriptions() {
109+
final EditText input = createEditText("initial");
110+
final Observable<String> observable = ViewObservable.input(input, false);
111+
112+
final Observer<String> observer1 = mock(Observer.class);
113+
final Observer<String> observer2 = mock(Observer.class);
114+
115+
final Subscription subscription1 = observable.subscribe(new TestObserver<String>(observer1));
116+
final Subscription subscription2 = observable.subscribe(new TestObserver<String>(observer2));
117+
118+
final InOrder inOrder1 = inOrder(observer1);
119+
final InOrder inOrder2 = inOrder(observer2);
120+
121+
input.setText("1");
122+
inOrder1.verify(observer1, times(1)).onNext("1");
123+
inOrder2.verify(observer2, times(1)).onNext("1");
124+
125+
input.setText("2");
126+
inOrder1.verify(observer1, times(1)).onNext("2");
127+
inOrder2.verify(observer2, times(1)).onNext("2");
128+
subscription1.unsubscribe();
129+
130+
input.setText("3");
131+
inOrder1.verify(observer1, never()).onNext(anyString());
132+
inOrder2.verify(observer2, times(1)).onNext("3");
133+
subscription2.unsubscribe();
134+
135+
input.setText("4");
136+
inOrder1.verify(observer1, never()).onNext(anyString());
137+
inOrder2.verify(observer2, never()).onNext(anyString());
138+
139+
inOrder1.verify(observer1, never()).onError(any(Throwable.class));
140+
inOrder2.verify(observer2, never()).onError(any(Throwable.class));
141+
142+
inOrder1.verify(observer1, never()).onCompleted();
143+
inOrder2.verify(observer2, never()).onCompleted();
144+
}
145+
}

rxjava-contrib/rxjava-android/src/test/java/rx/android/operators/OperatorTextViewInputTest.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,11 +58,27 @@ private static EditText createEditText(final String value) {
5858
return text;
5959
}
6060

61+
@Test
62+
@SuppressWarnings("unchecked")
63+
public void testOverloadedMethodDefaultsWithoutInitialValue() {
64+
final TextView input = createTextView("initial");
65+
final Observable<TextView> observable = ViewObservable.text(input);
66+
runWithoutInitialValueTest(input, observable);
67+
}
68+
6169
@Test
6270
@SuppressWarnings("unchecked")
6371
public void testWithoutInitialValue() {
6472
final TextView input = createTextView("initial");
65-
final Observable<TextView> observable = ViewObservable.input(input, false);
73+
final Observable<TextView> observable = ViewObservable.text(input, false);
74+
runWithoutInitialValueTest(input, observable);
75+
}
76+
77+
/**
78+
* Helper method to run {@link #testOverloadedMethodDefaultsWithoutInitialValue} and
79+
* {@link #testWithoutInitialValue} which test the same functionality.
80+
*/
81+
private void runWithoutInitialValueTest(final TextView input, final Observable<TextView> observable) {
6682
final Observer<TextView> observer = mock(Observer.class);
6783
final Subscription subscription = observable.subscribe(new TestObserver<TextView>(observer));
6884

@@ -91,7 +107,7 @@ public void testWithoutInitialValue() {
91107
@SuppressWarnings("unchecked")
92108
public void testWithInitialValue() {
93109
final TextView input = createTextView("initial");
94-
final Observable<TextView> observable = ViewObservable.input(input, true);
110+
final Observable<TextView> observable = ViewObservable.text(input, true);
95111
final Observer<TextView> observer = mock(Observer.class);
96112
final Subscription subscription = observable.subscribe(new TestObserver<TextView>(observer));
97113

@@ -120,7 +136,7 @@ public void testWithInitialValue() {
120136
@SuppressWarnings("unchecked")
121137
public void testMultipleSubscriptions() {
122138
final TextView input = createTextView("initial");
123-
final Observable<TextView> observable = ViewObservable.input(input, false);
139+
final Observable<TextView> observable = ViewObservable.text(input, false);
124140

125141
final Observer<TextView> observer1 = mock(Observer.class);
126142
final Observer<TextView> observer2 = mock(Observer.class);
@@ -160,7 +176,7 @@ public void testMultipleSubscriptions() {
160176
@SuppressWarnings("unchecked")
161177
public void testTextViewSubclass() {
162178
final EditText input = createEditText("initial");
163-
final Observable<EditText> observable = ViewObservable.input(input, false);
179+
final Observable<EditText> observable = ViewObservable.text(input, false);
164180
final Observer<EditText> observer = mock(Observer.class);
165181
observable.subscribe(new TestObserver<EditText>(observer));
166182

@@ -176,7 +192,7 @@ public void testTextViewSubclass() {
176192
@SuppressWarnings("unchecked")
177193
public void testLegacyStringObservableCompatibility() {
178194
final EditText input = createEditText("initial");
179-
final Observable<String> observable = ViewObservable.input(input, false)
195+
final Observable<String> observable = ViewObservable.text(input, false)
180196
.map(new Func1<EditText, String>() {
181197

182198
@Override

0 commit comments

Comments
 (0)