Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check the list size or for empty list in Paging 3 library

I've been able to successfully implement the new alpha07 version of Paging 3 library by following the instructions available here: https://developer.android.com/topic/libraries/architecture/paging/v3-paged-data#guava-livedata

However, now I am in need of checking whether the returned list is empty or not in order to show a view or a text to the user, but I am not able to attach any checks in the flow structure of their paging design.

Currently this is how I have my code in Java in my onViewCreated after following their guides:

        MyViewModel viewModel = new ViewModelProvider(this).get(MyViewModel.class);

        LifecycleOwner lifecycleOwner = getViewLifecycleOwner();
        Lifecycle lifecycle = lifecycleOwner.getLifecycle();
        Pager<Integer, MyEntity> pager = new Pager<>(new PagingConfig(10), () -> viewModel.getMyPagingSource());
        LiveData<PagingData<MyEntity>> pagingDataLiveData = PagingLiveData.cachedIn(PagingLiveData.getLiveData(pager), lifecycle);

        pagingDataLiveData.observe(lifecycleOwner, data -> adapter.submitData(lifecycle, data));

I tried attaching a .filter on my data in the adapter.submitData(lifecycle, data), but it never receives null items despite the list being empty.

How can I check when the data submitted to the adapter is empty in this scenario? I couldn't find any pointers in their documentation.

EDIT: This is the solution I found, posting here because the selected answer is not strictly speaking the solution nor is it in java, but is the one that lead me to it.

I had to attach a LoadStateListener to my adapter, listen for when the LoadType is REFRESH and the LoadState is NotLoading, then check if the adapter.getItemCount is 0.

It's possible a different LoadType is more appropriate for this scenario, but the refresh is working so far for me so I went with that one.

Sample example:

// somewhere when you initialize your adapter
...
myAdapter.addLoadStateListener(this::loadStateListener);
...
private Unit loadStateListener(@Nonnull CombinedLoadStates combinedLoadStates) {

    if (!(combinedLoadStates.getRefresh() instanceof LoadState.NotLoading)) {
        return Unit.INSTANCE; // this is the void equivalent in kotlin
    }

    myView.setVisibility(adapter.getItemCount() == 0 ? View.VISIBLE : View.INVISIBLE);

    return Unit.INSTANCE; // this is the void equivalent in kotlin

}

NOTE: We have to return Unit.INSTANCE because that listener is in kotlin and that code is being used in java, returning this is the equivalent of not returning anything in java (void).

like image 428
Shadow Avatar asked Oct 21 '20 18:10

Shadow


People also ask

How to check PagingData is empty?

FYI: You can use submitData(PagingData. empty()) to clear the list. You're right that re-using PagingSource will cause issues.

How can I get data from PagingData?

Display the paged data in your UI Create an instance of your PagingDataAdapter class. Pass the PagingDataAdapter instance to the RecyclerView list that you want to display your paged data. Observe the PagingData stream, and pass each generated value to your adapter's submitData() method.

What is Library pagination?

The Paging Library lets you load data directly from your backend using keys that the network provides. Your data can be uncountably large. Using the Paging Library, you can load data into pages until there isn't any data remaining. You can observe your data more easily.


1 Answers

The PagingData operators operate on individual items, so they won't get triggered if the page is empty.

Instead you want to check PagingDataAdapter.itemCount after the page has loaded, by observing loadStateFlow.

loadStateFlow.map { it.refresh }
    .distinctUntilChanged()
    .collect {
        if (it is NotLoading) {
            // PagingDataAdapter.itemCount here
        }
    }

Btw, null is a special value in Paging that denotes a placeholder, so you should not give Paging pages containing nulls, this is why the lower bound for the Value generic is non-null Any rather than Any?

like image 61
dlam Avatar answered Nov 11 '22 19:11

dlam