Initial data from ListAdapter gets erased when using DiffUtil.ItemCallback

438 Views Asked by At

In my app I have two LiveData objects, one for getting items from 0-10 and second to get the items from 11-20. I'm trying to load the data in a RecyclerView but instead of having 20 items, the first 10 (0-10) are replaces with new 10 (11-20). This is what I have tried:

recyclerView = findViewById(R.id.recycler_view);
adapter = new ItemsAdapter();
recyclerView.setAdapter(adapter);
viewModel = new ViewModelProvider(this).get(ItemListViewModel.class);

To get items from 0-10 I use this method:

private void getInitialItems() {
    ItemListLiveData liveData = viewModel.getItemsLiveData();
    liveData.observe(this, itemtList -> adapter.submitList(itemtList));
}

To get items from 11-20 I use this method:

private void getNextlItems() {
    ItemListLiveData liveData = viewModel.getItemsLiveData();
    liveData.observe(this, itemtList -> adapter.submitList(itemtList));
}

This is my ViewModel class:

public class ItemListViewModel extends ViewModel {
    private ItemListRepository repository = new ItemListRepository();

    ItemListLiveData getItemsLiveData() {
        return repository.getItemListLiveData();
    }
}

In the repository I only get the items from a back-end server. This is my adapter class:

public class ItemsAdapter extends ListAdapter<Item, ItemsAdapter.ItemViewHolder> {
    ItemsAdapter() {
        super(diffCallback);
    }

    @NonNull
    @Override
    public ItemViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        //Inflate the view
    }

    @Override
    public void onBindViewHolder(@NonNull final ItemViewHolder holder, int position) {
        //Bind the Item according to position
    }

    private static DiffUtil.ItemCallback<Item> diffCallback = new DiffUtil.ItemCallback<Item>() {
        @Override
        public boolean areItemsTheSame(@NonNull Item oldItem, @NonNull Item newItem) {
            return oldItem.id.equals(newItem.id);
        }

        @Override
        public boolean areContentsTheSame(@NonNull Item oldItem, @NonNull Item newItem) {
            return oldItem.equals(newItem);
        }
    };
}

My expectation is when using DiffUtil.ItemCallback to get both lists as a cumulative list since all the objects are different. Even if I pass both lists to the same adapter, I end up having only ten items (11-20). How to use submit list so I can have 20 items in my list and not only 10 (11-20)?

1

There are 1 best solutions below

8
On BEST ANSWER

DiffUtil.ItemCallback is used for animating smoothly changes in dataset in adapter.

For example if you have have 10 items, than submit list with 9 items that were contained in previous 10, DiffUtil.ItemCallback will determine difference between old and new list, which position that element was and animate changes accordingly. What you are looking for in your case is Pagination where you can expand/show items while scrolling.

You don't need two LiveData for this one, you cast fetch data from some source add it to LiveData of Pagination. First it will be showed 10 items, then if you scroll to end another 10, and so on. You can adjust type of pagination by your needs with provided Configuration.

To do all that without Pagination.

    liveData.observe(this, itemtList -> adapter.submitList(adapter.getCurrentList().addAll(itemtList)));

Get previous data, on top of that data add new data and it will all be shown.