Best way to show a loading/progress indicator?
Asked Answered
L

6

173

What is the best way to show a loading spinner while the app is waiting for a response from the server?

Can this be done programmatically? So that I don't have to add the load spinner in the xml file?

Lefton answered 11/10, 2012 at 14:23 Comment(0)
P
312

ProgressDialog is deprecated from Android Oreo. Use ProgressBar instead

ProgressDialog progress = new ProgressDialog(this);
progress.setTitle("Loading");
progress.setMessage("Wait while loading...");
progress.setCancelable(false); // disable dismiss by tapping outside of the dialog
progress.show();
// To dismiss the dialog
progress.dismiss();

OR

ProgressDialog.show(this, "Loading", "Wait while loading...");

Read more here.

By the way, Spinner has a different meaning in Android. (It's like the select dropdown in HTML)

Playreader answered 11/10, 2012 at 14:50 Comment(11)
From the Android Developer website: STYLE_SPINNER Creates a ProgressDialog with a circular, spinning progress bar.Weeks
This works, but when I tested this, I could dismiss the dialog by touching the screen outside of it or pressing the Back button. I fixed this by adding a call to progress.setCancelable(false);.Bilyeu
Thanks for the bottom comment. I was going crazy because I was trying to get 'spinner' to work for an hour.Cootie
superb, now I can use progress dialogGloat
ProgressDialog was deprecated in Android O developer.android.com/reference/android/app/ProgressDialog.htmlSeldon
Progress dialogs are bad UX in general. Avoid them.Hessenassau
ProgressDialog is now deprecated and should be avoided.Lowry
@IvanSemkin Any suggestions on alternatives to be used instead?Cowper
@BabkenVardanyan as written in documentation: ProgressDialog is a modal dialog, which prevents the user from interacting with the app. Instead of using this class, you should use a progress indicator like ProgressBar, which can be embedded in your app's UI. Alternatively, you can use a notification to inform the user of the task's progress. Sometimes I use also a SwipeRefreshLayout that shows a loading indicator and could be useful also to refresh in case of network failure. It can be activated/deactivated programmatically, but you need to insert it in layout xml.Constrain
@Constrain Good points. However I am looking for a solution that doesn't clutter my layout xml, and notifications is a different thing altogether.Cowper
anything in android that was once easy and quick to implement has been deprecated as a general rule. if it makes life easy, it's been deprecated.Yate
S
29

ProgressDialog has become deprecated since API Level 26 https://developer.android.com/reference/android/app/ProgressDialog.html

I include a ProgressBar in my layout

   <ProgressBar
        android:layout_weight="1"
        android:id="@+id/progressBar_cyclic"
        android:visibility="gone"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:minHeight="40dp"
        android:minWidth="40dp" />

and change its visibility to .GONE | .VISIBLE depending on the use case.

    progressBar_cyclic.visibility = View.VISIBLE
Soidisant answered 8/2, 2018 at 9:46 Comment(2)
Not sure, but does the progressBar run always in background(just hidden from the UI) after making it invisible?Hyperspace
@Hyperspace if you set it to View.GONE, it doesn't render in UI at all and has no negative effect to performance. View.INVISIBLE is like making it transparent, but it's in UI thus worse for performance.Vizzone
E
16

Use ProgressDialog

ProgressDialog.show(Context context, CharSequence title, CharSequence message);

enter image description here

However this is considered as an anti pattern today (2013): http://www.youtube.com/watch?v=pEGWcMTxs3I

Edmiston answered 11/10, 2012 at 14:31 Comment(2)
@artworkadシ So what aspect of this is considered bad -- is the accepted answer an example of the same anti-pattern? And what is recommended to do instead? Linking to a offsite video about multiple UX issues does not really improve this answer.Centro
ProgressDialog was deprecated in Android O developer.android.com/reference/android/app/ProgressDialog.htmlSeldon
P
11

Actually if you are waiting for response from a server it should be done programatically. You may create a progress dialog and dismiss it, but then again that is not "the android way".

Currently the recommended method is to use a DialogFragment :

public class MySpinnerDialog extends DialogFragment {

    public MySpinnerDialog() {
        // use empty constructors. If something is needed use onCreate's
    }

    @Override
    public Dialog onCreateDialog(final Bundle savedInstanceState) {

        _dialog = new ProgressDialog(getActivity());
        this.setStyle(STYLE_NO_TITLE, getTheme()); // You can use styles or inflate a view
        _dialog.setMessage("Spinning.."); // set your messages if not inflated from XML

        _dialog.setCancelable(false);  

        return _dialog;
    }
}

Then in your activity you set your Fragment manager and show the dialog once the wait for the server started:

FragmentManager fm = getSupportFragmentManager();
MySpinnerDialog myInstance = new MySpinnerDialog();
}
myInstance.show(fm, "some_tag");

Once your server has responded complete you will dismiss it:

myInstance.dismiss()

Remember that the progressdialog is a spinner or a progressbar depending on the attributes, read more on the api guide

Pryce answered 11/10, 2012 at 14:56 Comment(5)
ProgressDialog.show(Context context, CharSequence title, CharSequence message); Passing title parameter as empty string removes the title: ProgressDialog.show(context, "", "Loading..");Oracular
Fine example, though it was still possible for me to use the back button. I think it is because of your variable dlgAlert (and where is that coming from btw? :)). Anyway - since you are extending dialogfragment, you can just call setCancelable(false) and it will work.Extemporary
Committing fragment transactions at an indeterministic time when the server returns a response does not seem to be fool-proof. For example, when the response comes back, the activity that hosts the fragment may be in the wrong state. Any solution?Weywadt
Make sure you're importing android.support.v4.app.DialogFragment and not android.app.DialogFragment, or you can't use getSupportFragmentManager (see #27514838)Nicollenicolson
ProgressDialog was deprecated in Android O developer.android.com/reference/android/app/ProgressDialog.htmlSeldon
P
6

This is how I did this so that only one progress dialog can be open at a time. Based off of the answer from Suraj Bajaj

private ProgressDialog progress;



public void showLoadingDialog() {

    if (progress == null) {
        progress = new ProgressDialog(this);
        progress.setTitle(getString(R.string.loading_title));
        progress.setMessage(getString(R.string.loading_message));
    }
    progress.show();
}

public void dismissLoadingDialog() {

    if (progress != null && progress.isShowing()) {
        progress.dismiss();
    }
}

I also had to use

protected void onResume() {
    dismissLoadingDialog();
    super.onResume();
}
Parliamentarian answered 16/1, 2014 at 14:40 Comment(1)
ProgressDialog was deprecated in Android O developer.android.com/reference/android/app/ProgressDialog.htmlSeldon
L
0

Here comes the one and only version of "how to create a progress dialog because our loved ProgressDialog is deprecated" in Java:

Note: Used with Android 33.

    private AlertDialog progressAlertDialog = createProgressDialog(currentActivity / this);

    private AlertDialog createProgressDialog(AppCompatActivity currentActivity) {
        LinearLayout vLayout = new LinearLayout(currentActivity);
        vLayout.setOrientation(LinearLayout.VERTICAL);
        vLayout.setPadding(50, 50, 50, 50);
        vLayout.addView(new ProgressBar(currentActivity, null, android.R.attr.progressBarStyleLarge));

        return new AlertDialog.Builder(currentActivity)
                .setCancelable(false)
                .setView(vLayout)
                .create();
    }

    public void displayProgressDialog() {
        if (!progressAlertDialog.isShowing()) {
            progressAlertDialog.show();
        }
    }

    public void hideProgressDialog() {
        progressAlertDialog.dismiss();
    }
Landers answered 8/10, 2023 at 15:4 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.