Наблюдайте за изменениями текста и фильтруйте список с помощью RxAndroid

Чтобы наблюдать за изменениями текста в EditText -

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

И чтобы отфильтровать список -

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);
                        }
                    }
                });

Как объединить оба, чтобы отфильтровать фиксированный список элементов?

Обновить

Я изменил код на основе ответа, но он все еще не работает.

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);
                }
            });

person mjosh    schedule 03.04.2016    source источник


Ответы (1)


Я бы сделал это следующим образом:

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>>() {
          // ...
        });
person Michael    schedule 03.04.2016
comment
Можете ли вы посмотреть обновленный код на основе вашего ответа. Это все еще не работает. - person mjosh; 03.04.2016
comment
Список не фильтруется на основе изменения текста в SearchView. - person mjosh; 03.04.2016
comment
Что делает mItemListAdapter.notifyDataSetChanged(items);? - person Michael; 03.04.2016
comment
Изменяет базовые данные внутри адаптера. - person mjosh; 03.04.2016
comment
Он звонит notifyDataSetChanged()? - person Michael; 03.04.2016
comment
Отредактировал ваш ответ, изменения пользовательского интерфейса должны быть сделаны в потоке Schedulers.io(). - person mjosh; 03.04.2016
comment
Изменения выполняются в планировщике, который вы передаете observeOn(). В данном случае это AndroidSchedulers.mainThread(). - person Michael; 03.04.2016