Форум программистов, компьютерный форум, киберфорум
Наши страницы
Программирование Android
Войти
Регистрация
Восстановить пароль
 
arvalon
21 / 6 / 2
Регистрация: 26.10.2012
Сообщений: 205
Записей в блоге: 1
1

RXJava как скомбинировать два Observable так что бы один прерывал другой?

13.09.2019, 15:01. Просмотров 130. Ответов 6

Доброго для.
Есть задача. Имеем EditText, необходимо получать из него вводимые значения по нажатию кнопки Enter (Go) на клавиатуре ИЛИ по истечении определённого времени. Если нажатие по клавиатуре было произведено до истечения таймаута - отбрасывать дублирующую отправку введённого текста. Сделать Observable для каждой отдельной комбинации получилось, но соединить всё вместе не удаётся.

Итак, имеется EditText:
Кликните здесь для просмотра всего текста
Java
1
2
3
EditText ed = findViewById(R.id.edit_text);
ed.setImeOptions(EditorInfo.IME_ACTION_GO);
ed.setInputType(EditorInfo.IME_ACTION_GO);


Observable, выпускающий события нажатия на Go:

Java
1
2
3
Observable<CharSequence> editorActionObservable = RxTextView.editorActionEvents(ed)
                .filter(predicate)
                .map(event -> ed.getText());
Функция-предикат, пропускающая только нажатия на Go на экранной клавиатуре или Enter на аппаратной (если она есть, это условие задачи), переданная в фильтр Observable'выше
Java
1
2
3
4
Predicate<TextViewEditorActionEvent> predicate = (event ->
                event.actionId() == EditorInfo.IME_ACTION_GO
                || (event.keyEvent().getKeyCode() == KeyEvent.KEYCODE_ENTER
                && event.keyEvent().getAction() == KeyEvent.ACTION_UP ));
Второй Observable, основанный на изменениях текста в текстовом поле и выпускающий события с таймаутом, объединяется с первым Observable'ом Action-событий GO с помощью mergeWith(editorActionObservable).

Java
1
2
3
4
5
6
Disposable textChangedEvent =  RxTextView.textChanges(ed)
                .debounce(2, TimeUnit.SECONDS)
                .filter(text -> text.length() > 2)
                .mergeWith(editorActionObservable)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(charSequence -> Log.d("LOGTAG", "Search string "+charSequence));
Соответственно получается так что если ввести текст, удовлетворяющий всем условиям второго Observable (textChangedEvent) а потом нажать Go - событие в подписчик приходит дважды - сначала по Go а потом по Timeout'ту. А можно как-то сделать так что событие нажатия клавиатуры сбрасывало/подавляло то что отложено (остановленное в .debounce(2, TimeUnit.SECONDS))? Среди более сотни операторов так и не могу подобрать подходящую комбинацию. Ещё пробовал amb но этот оператор один раз делает выбор между из всех Observable тот который первый испустил событие и отбрасывает все остальные, такое поведение не то что нужно.
Знатоки RXJava, подскажите как быть?
0
QA
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
13.09.2019, 15:01
Ответы с готовыми решениями:

RxJava Observable.from из BroadcastReceiver
Здравствуйте. Недавно начал внедрять rxJava и столкнулся со сложностью: Есть BroadcastReceiver...

Как изменить программу так, чтобы было два потока:соотвественно один родительский, другой дочерний
Как изменить программу так, чтобы было два потока:соотвественно один родительский, другой дочерний,...

Не получается перемножить два вектора, один комплексный другой его комплексно-сопряженный, так чтобы получился вектор с
Не получается скалярно перемножить два вектора, один комплексный другой его комплексно-сопряженный,...

Как сделать так что я мог умножать не на два числа а на 3,4,5 и так далее?
Вот код: #include &lt;iostream&gt; #include &lt;conio.h&gt; using namespace std; int main(){ float...

Как сделать так,чтобы один круг не закрашивал другой?
См.Скрин. Как сделать так,чтобы они были как бы оба &quot;прозрачными&quot;? Сам скрин

6
ExFau$t
924 / 733 / 217
Регистрация: 08.05.2012
Сообщений: 3,534
13.09.2019, 16:05 2
Попробуй этот https://rxmarbles.com/#race
0
arvalon
21 / 6 / 2
Регистрация: 26.10.2012
Сообщений: 205
Записей в блоге: 1
13.09.2019, 16:17  [ТС] 3
Цитата Сообщение от ExFau$t Посмотреть сообщение
Попробуй этот https://rxmarbles.com/#race
Хм, не могу найти такой оператор в RXJava, кажется он есть только в RxJS?
0
ExFau$t
924 / 733 / 217
Регистрация: 08.05.2012
Сообщений: 3,534
13.09.2019, 16:26 4
А, ну значит этот: http://reactivex.io/documentation/operators/amb.html
Не понял, что тут не подходит.
0
arvalon
21 / 6 / 2
Регистрация: 26.10.2012
Сообщений: 205
Записей в блоге: 1
13.09.2019, 16:34  [ТС] 5
Цитата Сообщение от ExFau$t Посмотреть сообщение
А, ну значит этот: http://reactivex.io/documentation/operators/amb.html
Не понял, что тут не подходит.
C amb получается так что на этом операторе один раз на всё время подписки выбирается Observable, первым выпустивший событие. Второй игнорируется всё время. А нужно что бы последующий и ввод текста и клики по Go совместно работали и выпускалось событие прошедшее все фильтры первым.
0
ExFau$t
924 / 733 / 217
Регистрация: 08.05.2012
Сообщений: 3,534
13.09.2019, 16:49 6
Ну случилось событие начала ввода, слушаем кнопку или ждём 2 секунды, дождались чего-то - выполнился поток и всё. Можно хоть 100 раз повторять, что не так?
0
arvalon
21 / 6 / 2
Регистрация: 26.10.2012
Сообщений: 205
Записей в блоге: 1
13.09.2019, 16:53  [ТС] 7
Цитата Сообщение от ExFau$t Посмотреть сообщение
слушаем кнопку или ждём 2 секунды
Вот, вот в этой фразе похоже что вся загвоздка. Описать это в терминах rx-цепочек не удаётся. Если ввести текст и успеть нажать кнопку до истечения 2 секунд - два события приходят в подписчик. А хотелось бы одно, которое запустилось нажатием кнопки.
0
13.09.2019, 16:53
Answers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
13.09.2019, 16:53

Есть два списка: один [a, b, c], другой [1, 2, 3]. Нужно вывести один список вида [a-1, b-2, c-3]
Помогите решить, пожалуйста. Есть два списка: один , другой . Нужно вывести один список вида

Как правильно подключить два винчестера(один sata, другой ide)?
Здравствуйте. Подскажите, как правильно подключить два винчестера(один sata, другой ide)? На sata...

Как в проэкт запихать два срр-файла (один вызывает другой)
Тело ф-ии в одном .срр а Маin в другом .срр как это сделать?? Есть проэкт. в папке Source files...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
7
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.