Created
August 16, 2017 06:28
-
-
Save ViliusKraujutis/765b3eb5527bbc42886ba56c8f2dcf5f to your computer and use it in GitHub Desktop.
Use RxJava to detect changes
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<android.support.constraint.ConstraintLayout | |
xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:app="http://schemas.android.com/apk/res-auto" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context="lt.andro.learnrxjava.MainActivity" | |
> | |
<TextView | |
android:id="@+id/main_output" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="Hello World!" | |
app:layout_constraintLeft_toLeftOf="parent" | |
app:layout_constraintTop_toTopOf="parent" | |
/> | |
<EditText | |
android:id="@+id/main_input1" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="16dp" | |
android:layout_marginRight="16dp" | |
android:layout_marginTop="16dp" | |
android:ems="10" | |
android:inputType="textPersonName" | |
app:layout_constraintLeft_toLeftOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/main_output" | |
tools:text="Name" | |
/> | |
<EditText | |
android:id="@+id/main_input2" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="16dp" | |
android:layout_marginRight="16dp" | |
android:layout_marginTop="16dp" | |
android:ems="10" | |
android:inputType="textPersonName" | |
app:layout_constraintLeft_toLeftOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/main_input1" | |
tools:text="Name" | |
/> | |
<EditText | |
android:id="@+id/main_input3" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="16dp" | |
android:layout_marginRight="16dp" | |
android:layout_marginTop="16dp" | |
android:ems="10" | |
android:inputType="textPersonName" | |
app:layout_constraintLeft_toLeftOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/main_input2" | |
tools:text="Name" | |
/> | |
<EditText | |
android:id="@+id/main_input4" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="16dp" | |
android:layout_marginRight="16dp" | |
android:layout_marginTop="16dp" | |
android:ems="10" | |
android:inputType="textPersonName" | |
app:layout_constraintLeft_toLeftOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/main_input3" | |
tools:text="Name" | |
/> | |
<RadioGroup | |
android:id="@+id/main_radio_group" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_marginLeft="16dp" | |
android:layout_marginRight="16dp" | |
android:layout_marginTop="16dp" | |
app:layout_constraintLeft_toLeftOf="parent" | |
app:layout_constraintTop_toBottomOf="@id/main_input4" | |
> | |
<RadioButton | |
android:id="@+id/main_radio1" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="Radio1" | |
/> | |
<RadioButton | |
android:id="@+id/main_radio2" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="Radio2" | |
/> | |
<RadioButton | |
android:id="@+id/main_radio3" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="Radio3" | |
/> | |
<RadioButton | |
android:id="@+id/main_radio4" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:text="Radio4" | |
/> | |
</RadioGroup> | |
</android.support.constraint.ConstraintLayout> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
apply plugin: 'com.android.application' | |
android { | |
compileSdkVersion 26 | |
buildToolsVersion "26.0.1" | |
defaultConfig { | |
applicationId "lt.andro.learnrxjava" | |
minSdkVersion 15 | |
targetSdkVersion 26 | |
versionCode 1 | |
versionName "1.0" | |
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" | |
} | |
buildTypes { | |
release { | |
minifyEnabled false | |
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' | |
} | |
} | |
} | |
dependencies { | |
compile fileTree(dir: 'libs', include: ['*.jar']) | |
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', { | |
exclude group: 'com.android.support', module: 'support-annotations' | |
}) | |
compile 'com.android.support:appcompat-v7:26.0.0-alpha1' | |
compile 'com.android.support.constraint:constraint-layout:1.0.2' | |
testCompile 'junit:junit:4.12' | |
compile 'io.reactivex.rxjava2:rxandroid:2.0.1' | |
compile 'io.reactivex.rxjava2:rxjava:2.1.2' | |
compile 'com.jakewharton.rxbinding2:rxbinding:2.0.0' | |
compile 'com.jakewharton.rxbinding2:rxbinding-support-v4:2.0.0' | |
compile 'com.jakewharton.rxbinding2:rxbinding-appcompat-v7:2.0.0' | |
compile 'com.jakewharton.rxbinding2:rxbinding-design:2.0.0' | |
compile 'com.jakewharton.rxbinding2:rxbinding-recyclerview-v7:2.0.0' | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package lt.andro.learnrxjava; | |
import android.os.Bundle; | |
import android.support.v7.app.AppCompatActivity; | |
import android.text.Editable; | |
import android.text.TextUtils; | |
import android.widget.RadioGroup; | |
import android.widget.TextView; | |
import com.jakewharton.rxbinding2.InitialValueObservable; | |
import com.jakewharton.rxbinding2.widget.RxRadioGroup; | |
import com.jakewharton.rxbinding2.widget.RxTextView; | |
import com.jakewharton.rxbinding2.widget.TextViewAfterTextChangeEvent; | |
import java.util.Arrays; | |
import java.util.List; | |
import io.reactivex.Flowable; | |
import io.reactivex.Observable; | |
import io.reactivex.annotations.NonNull; | |
import io.reactivex.functions.Consumer; | |
import io.reactivex.functions.Function; | |
import io.reactivex.functions.Function4; | |
public class MainActivity extends AppCompatActivity { | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
TextView outputView = (TextView) findViewById(R.id.main_output); | |
TextView input1View = (TextView) findViewById(R.id.main_input1); | |
TextView input2View = (TextView) findViewById(R.id.main_input2); | |
TextView input3View = (TextView) findViewById(R.id.main_input3); | |
TextView input4View = (TextView) findViewById(R.id.main_input4); | |
RadioGroup inputRG = (RadioGroup) findViewById(R.id.main_radio_group); | |
outputView.setText("output"); | |
input1View.setText("input1"); | |
input2View.setText("input2"); | |
input3View.setText("input3"); | |
input4View.setText("input4"); | |
inputRG.check(R.id.main_radio2); | |
Consumer<? super CharSequence> output = RxTextView.text(outputView); | |
InitialValueObservable<TextViewAfterTextChangeEvent> rxInput1 = RxTextView.afterTextChangeEvents(input1View); | |
InitialValueObservable<TextViewAfterTextChangeEvent> rxInput2 = RxTextView.afterTextChangeEvents(input2View); | |
InitialValueObservable<TextViewAfterTextChangeEvent> rxInput3 = RxTextView.afterTextChangeEvents(input3View); | |
InitialValueObservable<TextViewAfterTextChangeEvent> rxInput4 = RxTextView.afterTextChangeEvents(input4View); | |
InitialValueObservable<Integer> rxInputRG = RxRadioGroup.checkedChanges(inputRG); | |
Observable<String> input1 = getInputAsStrings(rxInput1); | |
Observable<String> input2 = getInputAsStrings(rxInput2); | |
Observable<String> input3 = getInputAsStrings(rxInput3); | |
Observable<String> input4 = getInputAsStrings(rxInput4); | |
// combineV1(output, input1, input2, input3, input4); | |
combineV2(output, rxInputRG, input1, input2, input3, input4); | |
} | |
private void combineV2(Consumer<? super CharSequence> output, InitialValueObservable<Integer> rxInputRG, Observable<String> input1, Observable<String> input2, Observable<String> input3, Observable<String> input4) { | |
Function<Object[], Object> combiner = new Function<Object[], Object>() { | |
List<Object> initial; | |
@Override | |
public Object apply(@NonNull Object[] objects) throws Exception { | |
List<Object> combined = Arrays.asList(objects); | |
if (initial == null) { | |
initial = combined; | |
} | |
return initial.equals(combined); | |
} | |
}; | |
Observable | |
.combineLatest(combiner, Flowable.bufferSize(), input1, input2, input3, input4, rxInputRG) | |
.map(new Function<Object, String>() { | |
@Override | |
public String apply(@NonNull Object o) throws Exception { | |
return o.toString(); | |
} | |
}) | |
.doOnNext(output) | |
.subscribe(); | |
} | |
private void combineV1(Consumer<? super CharSequence> output, Observable<String> input1, Observable<String> input2, Observable<String> input3, Observable<String> input4) { | |
Function4<String, String, String, String, Boolean> checkForChanges = new Function4<String, String, String, String, Boolean>() { | |
String initialValue = ""; | |
@Override | |
public Boolean apply(@NonNull String s1, @NonNull String s2, @NonNull String s3, @NonNull String s4) throws Exception { | |
String combined = s1 + ":" + s2 + ":" + s3 + ":" + s4; | |
if (TextUtils.isEmpty(initialValue)) initialValue = combined; | |
return initialValue.equals(combined); | |
} | |
}; | |
Observable | |
.combineLatest(input1, input2, input3, input4, checkForChanges) | |
.map(new Function<Boolean, String>() { | |
@Override | |
public String apply(@NonNull Boolean aBoolean) throws Exception { | |
return aBoolean.toString(); | |
} | |
}) | |
.doOnNext(output) | |
.subscribe(); | |
} | |
private Observable<String> getInputAsStrings(Observable<TextViewAfterTextChangeEvent> inputs) { | |
Function<TextViewAfterTextChangeEvent, String> toString = new Function<TextViewAfterTextChangeEvent, String>() { | |
@Override | |
public String apply(@NonNull TextViewAfterTextChangeEvent changeEvent) throws Exception { | |
Editable editable = changeEvent.editable(); | |
if (editable != null) { | |
return editable.toString(); | |
} else { | |
return ""; | |
} | |
} | |
}; | |
return inputs.map(toString); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment