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).
FYI: You can use submitData(PagingData. empty()) to clear the list. You're right that re-using PagingSource will cause issues.
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.
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.
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 null
s, this is why the lower bound for the Value
generic is non-null Any
rather than Any?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With