D
D
Davron Asrorov2017-11-17 10:15:40
Android
Davron Asrorov, 2017-11-17 10:15:40

What to do if LiveData is updated later than scrolling by position to the last element in recycleView?

The situation is this. I used room to work with sqlite.
In the main activity we have recycleVIew, editText, button.
Enter numbers in editText, press button. There is an asynchronous addition to the database, and sending data to the server.
This is the button's 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() method; which is called in the onClick above
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);
                               }
                           }
                       }
        );
    }

As you can see above, the scroll method is called immediately after adding, but
LiveData does not always have time to update, which is why the scroll sometimes seems to stay in place.
Everything is complicated by the fact that the data also changes when a response is returned from the server, i.e. you cannot put the scroll method into model.list().observe();
So, what to do, what would scroll always work?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
D
davidnum95, 2017-11-17
@davidnum95

You now have the add method of the model running on a different thread, so scroll does not wait for data to be added. You need to make a listener that will fire when the data is successfully added / updated. Something like:

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

Wrote in the editor, there may be errors. the general principle must be understood.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question