1

I use GitHub search API for repositories searching. I know how I can result from the 3rd, 4th and etc pages. (https://api.github.com/search/repositories?q=java&page=2&per_page=30>) . For this in code I use this method:


      private void pagesPagination() {
            recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
                @Override
                public void onScrolled(@NonNull RecyclerView recyclerView, int dx, int dy) {
                    super.onScrolled(recyclerView, dx, dy);
                    if (!recyclerView.canScrollVertically(1) && dy != 0) {
                        if (layoutManager.findLastCompletelyVisibleItemPosition() ==
                                adapter.getItemCount() - 1) {
                          page++;
                     itemViewModel.searchItems(q, page, resultsPerPage);
                        itemViewModel.getNewItem().observe(MainActivity.this, responseObject -> {
                            adapter.addItems(responseObject.get(0).getItems());
                        });
                        }
                    }
                }
            });
        }
    }

 public class ItemViewModel extends AndroidViewModel {

    private ItemRepository itemRepository;
    private LiveData<Root> itemsResponseLiveData;
    private List<Root> items;
    private MutableLiveData<List<Root>> addedItems;

    public ItemViewModel(@NonNull Application application) {
        super(application);
    }

    public void init() {
        itemRepository = new ItemRepository();
        itemsResponseLiveData = itemRepository.getItemsResponseLiveData();
        items = new ArrayList<>();
        addedItems = new MutableLiveData<List<Root>>();
    }

    public Root addItem() {
     return itemsResponseLiveData.getValue();
    }

    public void searchItems(String q, int page, int resultsPerPage) {
        itemRepository.fetchData(q, page, resultsPerPage);
        items.add(addItem());
        addedItems.setValue(items);
    }

    public LiveData<Root> getItemsResponseLiveData() {
        return itemsResponseLiveData;
    }
    public MutableLiveData<List<Root>> getNewItem(){
        return addedItems;
    }
}

in adapter class:

public void addItems(List<Item> newItem ) {
    items.addAll(newItem);
    notifyDataSetChanged();
}

but if I scroll down this new list, I don't see previous results. Could I do that I see all results from all previous pages?

Julia
  • 369
  • 2
  • 12

1 Answers1

1

Your problem may be in how you used the LiveData inside the ViewModel,

If you use liveData.setValue(newList) this will not append the new items, instead, it will just set the value to be the new list only,

In your case you need to save the old items maybe in ArrayList and once you got new items append them first in the ArrayList, then use liveData.setValue(arrayList) to put all the items in the liveData and the adapter will receive all the items from it

Check this answer you will find more information and code about this solution

Notify Observer when item is added to List of LiveData

AmrDeveloper
  • 3,826
  • 1
  • 21
  • 30
  • AmrDeveloper I think you are right. it seems I am incorrectly notifying LiveData about the list change. I updated the question. can you please see what's wrong? – Julia Jun 05 '21 at 08:27
  • 1
    The problem is that first you got the data on itemsResponseLiveData, and created new itemsResponseLiveDatas with 0 items, and listen on the itemsResponseLiveData so you will get the new data only too, to solve this problem you have 2 option, first modify the repository code to have MutableLiveData and the ArrayList on it, then listen only to this live data, the other option, is to move to remove the LiveData object from the Repository and do the first idea in the ViewModel and that is the best one and will make the repository much cleaner – AmrDeveloper Jun 05 '21 at 09:11
  • 1
    The flow will be execute the repo request in ViewModel and append the result to the ArrayList, then add this ArrayList to the LiveData using setValue, and listen to this live data you will get the right values – AmrDeveloper Jun 05 '21 at 09:13
  • 1
    Ok, see, I changed ViewModel class (updated question) and in activity class I call this method: ` itemViewModel.getNewItem().observe(this, responseObject -> adapter.notifyDataSetChanged());` what am I doing wrong? – Julia Jun 05 '21 at 09:34
  • 1
    addItem should take the items from live data, not the empty ArrayList, should be like this addItem(itemsResponseLiveData.value); – AmrDeveloper Jun 05 '21 at 09:40
  • 1
    I changed to: ` public void addItem() { newItems.addAll(itemsResponseLiveData.getValue().getItems()); addedItems.setValue(newItems); }' but `itemsResponseLiveData.getValue().getItems()` is null always – Julia Jun 05 '21 at 10:00
  • 1
    don't take the items from it as global, do like this addItem(itemsResponseLiveData.value); and check before use it – AmrDeveloper Jun 05 '21 at 10:17
  • I updated my code in the question. It seems I have done all that you said, but list doesn't updated... – Julia Jun 05 '21 at 10:37
  • 1
    In searchItems you need to also to put the values in the arraylist and add the full arraylist in the live data too so you ca receive it – AmrDeveloper Jun 05 '21 at 11:32
  • 1
    I updated code. I am so sorry, but now `responseObject.get(0).getItems()` in activity class is always null. I understand that I am do obsessive, sorry, but I need help. – Julia Jun 05 '21 at 12:29
  • 1
    add item in the adapter should be done when you listen to the live data in observe method, all the work should done in ViewModel or repository to handle updating the livedata and the arraylist – AmrDeveloper Jun 05 '21 at 14:32
  • 1
    I understand. thank you very much for helping! – Julia Jun 05 '21 at 15:06