showing a progress bar with android paging library
Asked Answered
C

3

8

I'm using paging library and room, making my room db as the single layer of truth of my app. when fetching is done from the server using retrofit, i save the result locally in the db then i get the data from the db using paging library. I'm using BoundaryCallback .

@Override
    public void onZeroItemsLoaded() {
        requestAndSaveData();
    }
    @Override
    public void onItemAtEndLoaded(@NonNull Photo itemAtEnd) {
        requestAndSaveData();
}

 private void requestAndSaveData() {
        if (isRequestInProgress) return;
        isRequestInProgress = true;
        apiInterface.getPhotos(lastRequestPage, NETWORK_PAGE_SIZE).enqueue(new Callback<PhotoList>() {
            @Override
            public void onResponse(Call<PhotoList> call, Response<PhotoList> response) {
                if (response.isSuccessful()) {
                    cache.insertPhotos(response.body().getHits()); //todo only save 20 - 40 items
                    lastRequestPage++;
                    isRequestInProgress = false;
                    Log.i("deb", "number from boundary: " + response.body().getHits().size());
                }
}

When there is no item in the db or the user scroll to the last item i call requestAndSaveData() method that fetch the data from the server and save it into the db.

My question is how to show a progress bar at the bottom of the list while loading the next page from the server and saving it to the db as it may take a long time?

Caritta answered 23/6, 2018 at 17:2 Comment(2)
Do you want a progressbar at the end of list, or loading on surface of screen?Anxious
at the end of the listCaritta
L
6

First of all you could broaden your question scope by asking about how to show a loading indicator in the bottom of RecyclerView instead of narrowing it to the Paging Library..

Secondly, you can easily show a loading indicator in the bottom of your list by adding an extra cell to the list that is just only for showing load indicator, the similar idea is used here to show the network status:

https://github.com/googlesamples/android-architecture-components/blob/master/PagingWithNetworkSample/lib/src/main/java/com/android/example/paging/pagingwithnetwork/reddit/ui/PostsAdapter.kt

Lancelancelet answered 30/6, 2018 at 8:19 Comment(2)
@MarioBouchedid, The packaging is changed, you can find the class mentioned above here: github.com/googlesamples/android-architecture-components/blob/…Lancelancelet
They moved to paging 3 version. Here is old solution: github.com/android/architecture-components-samples/blob/…Pauperize
A
-1

Put a ProgressBar component inside your layout xml. Then change its visibility according to api call.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">

    <android.support.v7.widget.RecyclerView
        android:id="@+id/rv"
        style="@style/recyclerViewDefaultStyle" />

    <ProgressBar
        android:id="@+id/pb"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:visibility="gone" />

</LinearLayout>

In your activity

import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.ProgressBar;

import in.ks.widgetClock.R;

/**
 * Created by KHEMRAJ on 6/23/2018.
 */
public class Sample extends AppCompatActivity {
    ProgressBar progressBar;

    private void showProgressBar() {
        progressBar.setVisibility(View.VISIBLE);
    }

    private void hideProgressBar() {
        progressBar.setVisibility(View.GONE);
    }

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        progressBar = findViewById(R.id.pb);
        ...
    }

    private void requestAndSaveData() {
        if (isRequestInProgress) return;
        isRequestInProgress = true;
        showProgressBar();
        apiInterface.getPhotos(lastRequestPage, NETWORK_PAGE_SIZE).
                enqueue(new Callback<PhotoList>() {
                    @Override
                    public void onResponse(Call<PhotoList> call, Response<PhotoList> response) {
                        hideProgressBar();
                        if (response.isSuccessful()) {
                            cache.insertPhotos(response.body().getHits()); //todo only save 20 - 40 items
                            lastRequestPage++;
                            isRequestInProgress = false;
                            Log.i("deb", "number from boundary: " + response.body().getHits().size());
                        }
                    }
                }
    }

}
Anxious answered 23/6, 2018 at 17:38 Comment(3)
this will work fine in case of showing it on surface of screen, but i want to show it at the bottom of the list while loading the next pageCaritta
Note that i have used LinearLayout with orientation vertical, that will make your progressbar below list.Anxious
i want to achieve it like in this example:github.com/googlesamples/android-architecture-components/tree/…Caritta
D
-1

Provide placeholders in your UI:

I don't this is there any need of this if you are using placeholder and it has advantage as well see below:

No loading spinner necessary: Because the list size is already known, there's no need to alert users that more items are loading. The placeholders themselves convey that information.

Source : https://developer.android.com/topic/libraries/architecture/paging/ui

Drollery answered 7/2, 2020 at 11:41 Comment(1)
not needed only if you know the size of list beforehand.Coincidental

© 2022 - 2024 — McMap. All rights reserved.