In this tutorial, ozenero.com shows you way to integrate RxJava 2 into Android App, along with 3 simple examples that apply RxJava:
CompoundButton
(Switch
) updatesTextView
- Update TextView when text length in
EditText
changes - Reactive Text search
Set up Android environment
We use Android Studio (installer from https://developer.android.com/studio/) for development. It doesn’t support RxJava, so we need to add RxJava 2 library.
Add RxJava 2 dependencies
Open app/build.gradle file, add RxJava and RxBinding wrappers for UI:
dependencies { ... implementation 'io.reactivex.rxjava2:rxjava:2.1.7' implementation 'io.reactivex.rxjava2:rxandroid:2.0.1' implementation 'com.jakewharton.rxbinding2:rxbinding:2.0.0' }
Add Java 8 lambdas
We also need to add Java 8 to the configuration to use lambdas:
android { ... defaultConfig { ... compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } ... }
Simple RxJava in Android App examples
Example 1: CompoundButton (Switch) updates TextView
Layout:
<Switch android:id="@+id/switch_button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Press to Switch" /> <TextView android:id="@+id/text_view_1" android:layout_width="wrap_content" android:layout_height="wrap_content" />
We’re gonna make Switch
as an Observable.
– Create an Observable based on Switch
(CompoundButton
) change events using RxBindings library:
import com.jakewharton.rxbinding2.widget.RxCompoundButton; import io.reactivex.Observable; ... Switch switchButton = findViewById(R.id.switch_button); Observable<Boolean> switchObservable = RxCompoundButton.checkedChanges(switchButton);
– Subscribe with listener function, it makes textView1
change text according to whether switchButton
is checked
or not.
TextView textView1 = findViewById(R.id.text_view_1); switchObservable.subscribe(checked -> textView1.setText("Checked: " + checked));
Java code:
import com.jakewharton.rxbinding2.widget.RxCompoundButton; ... public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { ... Switch switchButton = findViewById(R.id.switch_button); TextView textView1 = findViewById(R.id.text_view_1); RxCompoundButton.checkedChanges(switchButton) .subscribe(checked -> textView1.setText("Checked: " + checked)); } }
Example 2: Update TextView when text length in EditText changes
Layout:
<EditText android:id="@+id/edit_text" android:layout_width="match_parent" android:layout_height="wrap_content" /> <TextView android:id="@+id/text_view_2" android:layout_width="wrap_content" android:layout_height="wrap_content" />
We’re gonna make Text input as an Observable.
– Create an Observable based on EditText
change events using RxBindings library:
import com.jakewharton.rxbinding2.widget.RxTextView; import io.reactivex.Observable; EditText editText = findViewById(R.id.edit_text); Observable<CharSequence> edtTextObservable = RxTextView.textChanges(editText);
Now the EditText
can be considered an emitter of string values over time.
– Subscribe with listener function, it makes textView2
say the text is “Too long!” if editText
is more than 6 characters.
edtTextObservable.subscribe(text -> textView2.setText(text.length() > 6 ? "Too long!" : ""));
Java code:
import com.jakewharton.rxbinding2.widget.RxTextView; ... public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); EditText editText = findViewById(R.id.edit_text); TextView textView2 = findViewById(R.id.text_view_2); RxTextView.textChanges(editText) .subscribe(text -> textView2.setText(text.length() > 6 ? "Too long!" : "")); } }
Example 3: Reactive Text Search
Layout:
<EditText android:id="@+id/edit_text_search" android:layout_width="match_parent" android:layout_height="40dp" android:background="#fff" android:paddingLeft="10dp" android:paddingRight="10dp" /> <ListView android:id="@+id/search_results" android:layout_width="match_parent" android:layout_height="147dp" android:layout_marginTop="5dp" android:background="#fff" />
Searches fewer than 3
characters will be filtered out, and search request will be only sent once the user hasn’t typed for 500ms
:
EditText editTextSearch = findViewById(R.id.edit_text_search); RxTextView.textChanges(editTextSearch) .doOnNext(text -> this.clearSearchResults()) .filter(text -> text.length() >= 3) .debounce(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::updateSearchResults);
Notice that, debounce()
operator will automatically switch the thread to a background. So we call .observeOn(AndroidSchedulers.mainThread())
before doing a UI operation (updateSearchResults()
) in the next step.
Java code:
import com.jakewharton.rxbinding2.widget.RxTextView; import java.util.ArrayList; import java.util.List; import java.util.Random; import java.util.concurrent.TimeUnit; import io.reactivex.android.schedulers.AndroidSchedulers; public class MainActivity extends AppCompatActivity { ArrayAdapterarrayAdapter; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); arrayAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1); ListView listView = findViewById(R.id.search_results); listView.setAdapter(arrayAdapter); EditText editTextSearch = findViewById(R.id.edit_text_search); RxTextView.textChanges(editTextSearch) .doOnNext(text -> this.clearSearchResults()) .filter(text -> text.length() >= 3) .debounce(500, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(this::updateSearchResults); } private void clearSearchResults() { arrayAdapter.clear(); } private void updateSearchResults(CharSequence text) { // Create some random results Random rand = new Random(); List list = new ArrayList<>(); for (int i = 0; i < 3; i++) { int n = rand.nextInt(100); list.add("" + text + "_" + n); } arrayAdapter.clear(); arrayAdapter.addAll(list); } }