mjosh mjosh - 5 months ago 44
Android Question

Observe text changes and filter list using RxAndroid

To observe text changes on EditText -

RxTextView.textChangeEvents(editText)
.subscribe(e -> log(e.text().toString()));


And to filter a list -

Observable.from(itemList)
.filter(item-> item.getName().toLowerCase().contains(search.toLowerCase()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<Item>() {
@Override
public void onCompleted() {
Utils.crossfade(mProgressView, recyclerHotelOption);
}

@Override
public void onError(Throwable e) {

}

@Override
public void onNext(Item item) {
if (mItemListAdapter == null) {
List<Item> itemList = new ArrayList<>();
itemList.add(item);
mItemListAdapter = new ItemListAdapter(mActivity, itemList);
recyclerHotelOption.setAdapter(mItemListAdapter);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(mActivity);
linearLayoutManager.setOrientation(LinearLayoutManager.HORIZONTAL);
recyclerHotelOption.setLayoutManager(linearLayoutManager);
} else {
mItemListAdapter.notifyDataSetChanged(item);
recyclerHotelOption.getLayoutManager().scrollToPosition(0);
}
}
});


How to combine both to filter fixed list of items?

Update

I changed the code based on the answer but it's still not working.

RxSearchView.queryTextChangeEvents(mSearchView)
.map(textViewTextChangeEvent -> textViewTextChangeEvent.toString().toLowerCase())
.switchMap(s -> Observable.from(items)
.filter(item-> item.getItemName().toLowerCase().contains(s.toLowerCase()))
.toList()).subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Observer<List<Item>>() {
@Override
public void onCompleted() {
}

@Override
public void onError(Throwable e) {
}

@Override
public void onNext(List<Item> items) {
mItemListAdapter.notifyDataSetChanged(items);
recyclerView.getLayoutManager().scrollToPosition(0);
}
});

Answer

I would do it in the following way:

Observable<CharSequence> textChanges = RxTextView.textChangeEvents(editText);
textChanges
    .map(search -> search.toString().toLowerCase())
    .switchMap(search ->
      Observable.from(itemList)
          .filter(item -> item.getName().toLowerCase().contains(search))
          .toList()
    )
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(
        new Observer<List<Item>>() {
          // ...
        });
Comments