godzeit
@godzeit
Android developer

Что делать если LiveData обновляется позже чем происходит scroll по позиции до последнего элемента в recycleView?

Ситуация такова. Я использовал room для работы с sqlite.
В главном activity у нас есть recycleVIew, editText, button.
Вводишь цифры в editText, жмешь button. Идет асинхронное добавление в базу, и отправка данных на сервер.

Это onClick кнопки
public void add(View view) {
        if (!text.getText().toString().equals("")) {
            model.add(text.getText().toString());
            recycler.smoothScrollToPosition(model.list.getValue().size());
            text.setText("");
        }
    }


Метод model.add(); который вызывается в onClick выше
public void add(final String bib) {
        service.submit(new Runnable() {
                           @Override
                           public void run() {
                               String time = df.format(Calendar.getInstance().getTime());
                               String point = sPref.getString("POINT", "");
                               long id = dataBase.BoxModel().addBox(new Box(bib, time, 0, point));
                               Log.d("SIZE ADD: ", ""+list.getValue().size());
                               try {
                                   Response<Result> response = App.getApi().send(sPref.getString("URL", ""), bib, time, point, 1).execute();
                                   if (response.code() == 200) {
                                       Log.d("ID IN: ", id+" "+bib+" "+time);
                                       dataBase.BoxModel().updateItemStatus(id, 1);
                                   }
                                   else {
                                       dataBase.BoxModel().updateItemStatus(id, -1);
                                   }
                               }
                               catch (Exception e) {
                                   dataBase.BoxModel().updateItemStatus(id, -1);
                               }
                           }
                       }
        );
    }


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

Всё осложняется тем, что данные так же изменяются при возвращении ответа от сервера, т.е нельзя засунуть метод scroll в model.list().observe();

Так, что же делать, что бы scroll всегда срабатывал?
  • Вопрос задан
  • 211 просмотров
Пригласить эксперта
Ответы на вопрос 1
@davidnum95
У вас сейчас метод add модели выполняется на другом потоке, соответственно scroll не дожидается добавления данных. Нужно сделать listener, который будет срабатывать при успешном добавлении/обновлении данных. Что то типа:
// Listener
public interface OnDataChangedListener {
    public void onSuccess();
}

// onClick
public void add(View view) {
        if (!text.getText().toString().equals("")) {
            model.add(text.getText().toString(), new OnDataChangedListener() {
                public void onSuccess() {
                    recycler.smoothScrollToPosition(model.list.getValue().size());
                }
            });
            text.setText("");
        }
}

// model.add
public void add(final String bib, OnDataChangedListener listener) {
        service.submit(new Runnable() {
                           @Override
                           public void run() {
                               String time = df.format(Calendar.getInstance().getTime());
                               String point = sPref.getString("POINT", "");
                               long id = dataBase.BoxModel().addBox(new Box(bib, time, 0, point));
                               Log.d("SIZE ADD: ", ""+list.getValue().size());
                               try {
                                   Response<Result> response = App.getApi().send(sPref.getString("URL", ""), bib, time, point, 1).execute();
                                   if (response.code() == 200) {
                                       Log.d("ID IN: ", id+" "+bib+" "+time);
                                       dataBase.BoxModel().updateItemStatus(id, 1);
                                       listener.onSuccess();
                                   }
                                   else {
                                       dataBase.BoxModel().updateItemStatus(id, -1);
                                   }
                               }
                               catch (Exception e) {
                                   dataBase.BoxModel().updateItemStatus(id, -1);
                               }
                           }
                       }
        );
    }

Писал в редакторе, могут быть ошибки. общий принцип должен быть понятен.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы