32

I've searched everywhere and I can't find a solution to this problem.

Basically I have a login screen and I'm trying to get a progress spinner to show up while it's logging in to the server (via a thread), and then dismiss it after the login is successful. It has to work while changing orientations.

I am using DialogFragment with the Android compatibility package to make a progress bar (can't find any documentation on it, only for basic\alert dialog) because showDialog() is deprecated now. Right now I just show a custom message box as a login spinner.

In Summary:

  • How can I set up a Progress spinner with DialogFragment.
  • How can I dismiss it in another thread after orientation changes.
Philipp Reichart
  • 20,085
  • 5
  • 54
  • 64
Jon
  • 483
  • 1
  • 4
  • 14

2 Answers2

60

For showing a progress spinner, just override DialogFragment.onCreateDialog() in your dialog fragment like this (no need for overriding onCreateView()):

@Override
public Dialog onCreateDialog(final Bundle savedInstanceState) {
    final ProgressDialog dialog = new ProgressDialog(getActivity());
    //
    dialog.setTitle(R.string.login_title);
    dialog.setMessage(getString(R.string.login_message));
    dialog.setIndeterminate(true);
    dialog.setCancelable(false);
    // etc...
    return dialog;
}

As for dismissing that dialog fragment from somewhere else, you'll need to get a hold of FragmentManager (from inside your next FragmentActivity or Fragment) and call popBackStack() on it (if you don't do any other fragment transaction in the meantime).

If there's more steps/fragment transactions between your progress dialog fragment and the next activity, you'll probably need one of the other popBackStack(...) methods that take an ID or tag to pop everything up to your progress dialog fragment off the stack.

Philipp Reichart
  • 20,085
  • 5
  • 54
  • 64
  • 1
    You have setTitle twice, think you meant, dialog.setMessage(R.string.login_message) – worked Oct 30 '11 at 20:54
  • @worked Thanks, I fixed it -- there's no `setMessage(int)` on `ProgressDialog`, though, so I had to use `setMessage(String)`. – Philipp Reichart Oct 30 '11 at 22:39
  • 17
    I'd like to add that the `DialogFragment` has a `dismiss` method which can be used in favor of popping the back stack. Just `findFragmentByTag`, cast to `DialogFragment` and `dismiss()` – Greyson Aug 23 '12 at 22:19
  • And how do you use the setProgress from the async task for example?The progressdialog is declared inside the oncreatedialog, right? – Maxrunner Nov 29 '12 at 15:59
  • @PhilippReichart, Would you please refer any complete example? – Md Mahbubur Rahman Dec 22 '12 at 06:57
  • Fragment still gets cancelled. Add this line before `return` to fix that: `setCancelable(false)` This way you also disallow cancel of the fragment that holds the dialog. More "complete example" (still without preventing cancel of fragment): https://gist.github.com/dhawalhshah/1355547 – OneWorld Sep 25 '13 at 11:51
  • `ProgressDialog` was deprecated in api 26. The recommended solution is to use a `ProgressBar` or a `Notification`: https://developer.android.com/reference/android/app/ProgressDialog.html – WindsurferOak Sep 11 '17 at 18:20
21

I know this is old question but I want to share much better solution for this

According to Android Development Protip:

"Stop using ProgressDialog,Inline indicators are your friend"

As Roman Nurik states:

enter image description here

This one's quick. Stop using ProgressDialog and other modal loading indicators. They're extremely interruptive and annoying, especially when:

  • You see one every time you switch tabs.

  • You can't Back out of them.

  • They say "Please wait." No thanks, I'd rather just uninstall.

Either show loading indicators inline with your content (e.g. http://developer.android.com/training/animation/crossfade.html) or better yet, load small amounts of data in the background so that you minimize the need to even show a loading indicator.

More about progress & activity in the design guidelines.

Michael Kohne
  • 11,516
  • 3
  • 43
  • 71
LOG_TAG
  • 17,968
  • 11
  • 68
  • 101
  • 1
    As a caution, when you copy the words of another, you must properly blockquote anything you copy from them, and you must provide a link to the original source. – Brad Larson Dec 02 '13 at 02:10
  • 1
    True enough, but what about cases where you can't proceed with the app until say something has been printed successfully? Because you can only update and save the data if the print was successful and if it was not, you need to give the user the chance to try again/change data etc. I have to yet find a way to handle all this without showing a wait spinner. – AgentKnopf Sep 22 '14 at 07:27
  • @Zainodis hide/invisible the inline progress bar and use Crouton to display the error message,you can change the Print button name to Re-Print. all depends on where you call ShowProgress(true) ShowProgress(false) to show the content. – LOG_TAG Sep 22 '14 at 10:02
  • @LOG_TAG interesting point regarding Crouton! I already made sth like this on my own without knowing it already existed, though in my case croutons can contain buttons and input fields as well :) - but definitely food for thought - thanks a lot! – AgentKnopf Sep 22 '14 at 10:27
  • 1
    Forgot I had this question up!. Times have changed since I posted that question so I'll accept this as it's more up to date with modern app design. – Jon Mar 15 '15 at 22:14
  • This answer is overrated. The reasons given for not using ProgressDialog in favor of "inline" indicators apply just as much to inline indicators as to dialogs. And the answer doesn't answer the question. Sure, you should try to avoid making the user wait. But that's a separate issue from "How do I indicate a 'busy' state when it's necessary to do so?" – LarsH Apr 04 '19 at 17:32