How to center progress indicator in ProgressDialog easily (when no title/text passed along)
Asked Answered
S

8

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.

Siam answered 12/7, 2010 at 4:33 Comment(0)
V
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.

Visual answered 12/7, 2010 at 6:8 Comment(26)
@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).Siam
@Mathias Lin: To answer your question I went through developer.android.com/intl/zh-TW/guide/topics/ui/themes.html. Try adding: <item name="android:gravity">center_vertical|center_horizontal</item>Visual
@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.Siam
@Mathias Lin Cool. Good luck with your app.Visual
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!?Vesuvius
@Visual 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.Cherise
I can't dismiss this dialog (progressDialog.dismiss(); does not work)? Any idea why?Publicly
@jul: It doesn't give you a NPE?Visual
@Visual 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...Publicly
Ok, I should have called it the static way. It works perfectly. Thanks.Publicly
@Macarse: i had tried this code, but progress bar is displaying when i press the Back Button Here is my code pastebin.com/etrthq6ZAvast
@Publicly I'm also having trouble dismissing the custom dialog, could either of you shed some light on how you called it statically? ThanksTentation
How can I have the progress bar rotating at a custom position instead of center?Publicly
Please add parent when declare style. This style can produce a lot of problems with new apis: parent="@android:style/Theme.Dialog"Rooker
@Tentation - In order to dismiss the dialog, do the following - MyProgressDialog progressDialog; progressDialog = MyProgressDialog.show(ItemListActivity.this, "title", "message"); progressDialog.dismiss();Deering
my progress dialog doesn't show any animation, i change the background color to black, it only shows a black box and no animationAlbric
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: <item name="android:windowNoTitle">true</item>Brasher
Superb...!! Works So Accurately...Good Work...Cheers!!Darfur
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.Zoubek
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?Jonna
@Visual 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 thoughJonna
@JuiCe: Remember it should be /res/styleVisual
@Visual not working in my activity <#15358074>Coil
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.Cutcliffe
this code is not running in my app dude what should i do i use fragment in my appOverburdensome
and error is java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layoutOverburdensome
C
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:

Camporee answered 2/4, 2012 at 19:46 Comment(0)
T
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();
    }

}
Tracheotomy answered 1/8, 2013 at 7:5 Comment(4)
This still adds a white background depending on your theme.Schappe
I think this is the easiest way to do it. Really well done, you saved me a lot of time!Schwann
really short , easiest way to do.Cancer
Only spinner, this is what I have been looking for a while, nice answer :)Paroicous
J
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>
Jacks answered 20/12, 2013 at 19:49 Comment(0)
V
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);
Vanadium answered 18/3, 2017 at 18:51 Comment(2)
tnx, the best answer for me.Hartsell
This solution is for >21 APISkinner
B
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();
}
Branham answered 22/11, 2011 at 5:36 Comment(0)
J
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);
Jaella answered 23/7, 2017 at 15:55 Comment(0)
G
-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

Gertrude answered 13/8, 2012 at 12:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.