62

When calling progressDialog = ProgressDialog.show(this, null, null, true); usually the developers wants to only show the progress indication image, and usually would it expect to be centered within the window (at least from regular UI design point of view). But the image is too far left, it seems that some padding/margin on the right hand side is still being calculated in for (optional) text on the right, although we're not passing any text as parameter. It would just make life little easier for a developer :) So we don't need to create a custom dialog only in order to have the progress indicator being centered by default.

(I filed this as a feature request at http://code.google.com/p/android/issues/detail?id=9697; please star it if you would also like to see this improved).

Now my questions:

  1. How can I easily center the progress image without having to entirely create my own custom alert dialog class? Any parameter I might have overlooked?

  2. Furthermore, how to set the background to transparent?

I'm also wondering about this: https://stackoverflow.com/questions/2866141/how-to-put-custom-animation-into-a-progressdialog I haven't actually tried it myself yet but if you cannot create custom animations, it means if you want a kind of animated progress indicator, you always need to extend the ProgressDialog class? Looking at the ProgressDialog class though, I don't find anything other than regular drawables though (ProgressDialog.java), they're not using AnimatedDrawable there.

Community
  • 1
  • 1
Mathias Conradt
  • 27,904
  • 20
  • 132
  • 186

8 Answers8

104

I did some testing and I feel that the best way to achieve this is doing a custom Dialog.

Here is an example of what I did. This will answer question number 2 but will give you an idea of how to fix question number 1.

public class MyProgressDialog extends Dialog {

    public static MyProgressDialog show(Context context, CharSequence title,
            CharSequence message) {
        return show(context, title, message, false);
    }

    public static MyProgressDialog show(Context context, CharSequence title,
            CharSequence message, boolean indeterminate) {
        return show(context, title, message, indeterminate, false, null);
    }

    public static MyProgressDialog show(Context context, CharSequence title,
            CharSequence message, boolean indeterminate, boolean cancelable) {
        return show(context, title, message, indeterminate, cancelable, null);
    }

    public static MyProgressDialog show(Context context, CharSequence title,
            CharSequence message, boolean indeterminate,
            boolean cancelable, OnCancelListener cancelListener) {
        MyProgressDialog dialog = new MyProgressDialog(context);
        dialog.setTitle(title);
        dialog.setCancelable(cancelable);
        dialog.setOnCancelListener(cancelListener);
        /* The next line will add the ProgressBar to the dialog. */
        dialog.addContentView(new ProgressBar(context), new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
        dialog.show();

        return dialog;
    }

    public MyProgressDialog(Context context) {
        super(context, R.style.NewDialog);
    }
}

All the static methods comes from this link, nothing strange, but the magic occurs in the constructor. Check that I pass as parameter an style. That style is the following:

<?xml version="1.0" encoding="utf-8"?>
<resources>
    <style name="NewDialog" parent="@android:Theme.Dialog">
        <item name="android:windowFrame">@null</item>
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsFloating">true</item>
        <item name="android:windowContentOverlay">@null</item>
        <item name="android:windowTitleStyle">@null</item>
        <item name="android:windowAnimationStyle">@android:style/Animation.Dialog</item>
        <item name="android:windowSoftInputMode">stateUnspecified|adjustPan</item>
        <item name="android:backgroundDimEnabled">false</item>
        <item name="android:background">@android:color/transparent</item>
    </style>
</resources>

The result of this is a ProgressBar rotating in the center of the screen. Without backgroundDim and without the Dialog box.

JLamkin
  • 711
  • 5
  • 17
Macarse
  • 87,001
  • 42
  • 169
  • 229
  • @Macarse: I got an additional question though ;) In case I (or my client.. ;) wants to actually keep the default window frame and background color - how can I still keep the frame (with it's rounded borders, etc. like in my screenshot)? Setting the bg color is obvious, but the parameter android:windowFrame=@null doesn't seem to matter much. If I leave out this line in above code, the default window frame would still not be displayed.; so it seems to have no effect. (so basically all I want is to center the progress indicator properly centered in the default dialog). – Mathias Conradt Jul 14 '10 at 02:09
  • @Mathias Lin: To answer your question I went through http://developer.android.com/intl/zh-TW/guide/topics/ui/themes.html. Try adding: center_vertical|center_horizontal – Macarse Jul 14 '10 at 15:43
  • @Macarese: thanks for looking that up. Meanwhile I used the approach to setting a custom drawable (xml defined) with rounded corners now as the background. So it's not the native window frame, but looks alike or similar effect. – Mathias Conradt Jul 15 '10 at 02:23
  • @Mathias Lin Cool. Good luck with your app. – Macarse Jul 15 '10 at 07:25
  • All of the above was very helpful. But I was looking for something else. I don't want a progress bar, but the spinner is just right for my situation. All I wanted was to just have the background color of my choice. Is it possible? I tried many variations of your examples, but they don't perfectly work. Any idea about this exact situation!? – Aman Alam Dec 24 '10 at 11:48
  • @Macarse i have found this answer very much useful. If i tried to set android:layout_gravity="center" then then title will be displayed along with progress bar. – Paresh Mayani May 02 '11 at 12:46
  • I can't dismiss this dialog (`progressDialog.dismiss();` does not work)? Any idea why? – jul May 17 '11 at 09:50
  • @jul: It doesn't give you a NPE? – Macarse May 17 '11 at 11:41
  • 1
    @Macarse No... I also tried: `progressDialog = new MyProgressDialog(ItemListActivity.this); progressDialog.show(ItemListActivity.this, "title", "message"); progressDialog.dismiss();` It's shown properly, but doesn't dismiss... – jul May 17 '11 at 12:09
  • Ok, I should have called it the static way. It works perfectly. Thanks. – jul May 17 '11 at 14:45
  • @Macarse: i had tried this code, but progress bar is displaying when i press the Back Button Here is my code http://pastebin.com/etrthq6Z – Sankar Ganesh PMP Jul 02 '11 at 11:54
  • 3
    @jul I'm also having trouble dismissing the custom dialog, could either of you shed some light on how you called it statically? Thanks – Millec8 Sep 14 '11 at 18:53
  • How can I have the progress bar rotating at a custom position instead of center? – jul Oct 12 '11 at 09:43
  • 7
    Please add parent when declare style. This style can produce a lot of problems with new apis: parent="@android:style/Theme.Dialog" – Kostadin May 30 '12 at 08:10
  • 4
    @Millec8 - In order to dismiss the dialog, do the following - MyProgressDialog progressDialog; progressDialog = MyProgressDialog.show(ItemListActivity.this, "title", "message"); progressDialog.dismiss(); – Raoul George Jun 07 '12 at 06:43
  • my progress dialog doesn't show any animation, i change the background color to black, it only shows a black box and no animation – Najeebullah Shah Jul 24 '12 at 08:23
  • 1
    For anyone show is wondering why it's not completely centered on the screen, it's because the title bar is still showing - remove that with: `true` – Neromancer Aug 18 '12 at 02:34
  • 1
    Superb...!! Works So Accurately...Good Work...Cheers!! – Haresh Chaudhary Aug 23 '12 at 06:09
  • Shouldn't your public MyProgressDialog(Context context) { super(context, R.style.NewDialog); } be private ? It will avoid a lot of confusions. As in only way to get dialog would be Static methods in that case. – suhas_sm Dec 05 '12 at 06:41
  • I am working with Gingerbread( Android 2.3 ) and I am getting errors with calling `R.style.NewDialog`. There is no `/style` directory and when I create one I get an error. Any ideas? – JuiCe Dec 14 '12 at 14:38
  • @Macarse No luck :( I create the `/style` folder with no error, add an XML file, gives me a `premature end of file` error, then I fill the file with the code above, the XML file loses its error, but the style folder still has an error icon, and my project will not run. Thanks anyway though – JuiCe Dec 14 '12 at 16:31
  • @JuiCe: Remember it should be `/res/style` – Macarse Dec 14 '12 at 16:54
  • @Macarse not working in my activity – duggu Mar 13 '13 at 06:40
  • 1
    How can I style this so that the spinner has the Holo.Light/Dark theme from ICS and up? Right now the spinner is the old Gingerbread style. Extending the style from `parent="@android:style/Theme.Holo.Light.Dialog"` or other variants doesn't work. – socoho Aug 17 '13 at 02:00
  • this code is not running in my app dude what should i do i use fragment in my app – Bhanu Sharma Nov 21 '13 at 12:22
  • and error is java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layout – Bhanu Sharma Nov 21 '13 at 12:30
32

Easy and customizable way:

Define animation: (res/drawable/loader_anim.xml)

<animated-rotate xmlns:android="http://schemas.android.com/apk/res/android"
android:drawable="@drawable/image_for_rotation"
android:pivotX="50%"
android:pivotY="50%" />

or:

<animation-list xmlns:android="http://schemas.android.com/apk/res/android" >
<item
android:drawable="@drawable/img_loader_frame1"
android:duration="150"/>
...
<item
android:drawable="@drawable/img_loader_frame2"
android:duration="150"/>
...
</animation-list>

then, define layout: (res/layout/loader.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/layout_root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_gravity="center_vertical|center_horizontal"> 
<ProgressBar
android:layout_width="200dp"
android:layout_height="200dp"
android:indeterminateDrawable="@drawable/loader_anim" />
</LinearLayout>

and then, instance progress dialog:

ProgressDialog dialog;
...
dialog = ProgressDialog.show(this,null,null);
dialog.setContentView(R.layout.loader);
...
process();
...
dialog.dismiss();

More info:

Richard Lalancette
  • 2,302
  • 21
  • 29
Hpsaturn
  • 2,612
  • 28
  • 35
24

I use the following, it requires no layout file, and puts a centered, borderless blocking progress bar in the middle of the screen.

private ProgressDialog progressDialog;


setUIToWait(true);

...long process...

setUIToWait(false);


private void setUIToWait(boolean wait) {

    if (wait) {
        progressDialog=ProgressDialog.show(this,null,null);
        progressDialog.setContentView(new ProgressBar(this));
    } else {
        progressDialog.dismiss();
    }

}
egalot
  • 241
  • 2
  • 4
19

If you want to display indeterminate progress bar only.

ProgressDialog progressDialog = ProgressDialog.show(this, null, null, true, false);
progressDialog.setContentView(R.layout.progress_layout);

And create a layout xml file with name "progress_layout.xml"

<?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" >

    <ProgressBar
        android:id="@+id/progressBar1"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center" />

</LinearLayout>
Thafer Shahin
  • 515
  • 5
  • 9
5

Just Do The Below Method To Get It Done

In res->values->styles add the below code

<style name="MyGravity" parent="android:Theme.Material.Dialog" ></style>

Then create yours ProgressDialog as mentioned below

ProgressDialog dialog = new ProgressDialog(ctx, R.style.MyGravity);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);
Arun Mohan
  • 201
  • 2
  • 11
2
//create Dialog by using below method

@Override
protected Dialog onCreateDialog(int id) {

    switch (id) {

    case DIALOG1_KEY: {
        Dialog dialog = new Dialog(this,R.style.NewDialog);
        dialog.setContentView(R.layout.progress);
        dialog.setCancelable(true);
        return dialog;
    }
    }
    return null;
}

//then in your onCreate () you can call like below

@Override

public void onCreate(Bundle savedInstatncestate)

{

final Handler mHandler = new Handler();
showDialog(DIALOG1_KEY);
new Thread() {
public void run() {
try {
    sleep(3000);
    Runnable r = new Runnable() 
    {
    public void run() 
    {
               //do your background process

             dismissDialog(DIALOG1_KEY);
    }

        };
mHandler.post(r);
     } catch (Exception e) {
     }
   }
}.start();
}
0

You can always add one ProgressBar in all your activities where you might want to show centered ProgressDialog. Use following in acitivity.xml As:

<ProgressBar
android:layout_width="wrap_content"
android:layout_height="wrap_content" 
android:id="@+id/progressBar"
android:layout_centerInParent="true"
android:visibility="gone"/>

In your Acitivity.java, use

ProgressBar bar = new Progress();
bar = (ProgressBar) findViewById(R.id.progressBar);

Now when you want to show the ProgressBar, just set its visibility to visible, and to cancel, set visibility to gone.

bar.setVisibility(View.VISIBLE);
bar.setVisibility(View.GONE);
Rathore
  • 216
  • 3
  • 8
-1

Using ProgressBar and adding it to LinearLayout worked in my Case as follows:

ProgressBar mSpinner = new ProgressBar(this); 
mSpinner.setLayoutParams(new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
mSpinner.setBackgroundResource(R.drawable.loading_1);
mSpinner.setIndeterminate(true);

enter image description here

Bo Persson
  • 86,087
  • 31
  • 138
  • 198
Nishant
  • 93
  • 4