如何轻松地将ProgressDialog中的进度指示器居中(当没有传递标题/文本时)

62

调用progressDialog = ProgressDialog.show(this, null, null, true);时,开发人员通常只想显示进度指示图像,并期望该图像从界面设计的常规角度来看应居中显示在窗口中。

但是该图像太偏左了,似乎仍然为右侧的(可选)文本计算了一些填充/边距,尽管我们未传递任何文本作为参数。

这将使开发人员的生活变得更加轻松 :) 因此,我们不需要创建自定义对话框,仅为了使默认情况下的进度指示器居中。

(我已将此作为功能请求提交到http://code.google.com/p/android/issues/detail?id=9697;如果您也希望看到此改进,请对其进行评星)。

现在我的问题:

  1. 如何轻松地将进度图像居中,而无需完全创建自己的自定义警报对话框类? 我可能忽略了哪些参数吗?

  2. 此外,如何将背景设置为透明?

我还在思考这个:https://stackoverflow.com/questions/2866141/how-to-put-custom-animation-into-a-progressdialog,我自己还没有尝试过,但是如果您无法创建自定义动画,这意味着如果您想要一种动画效果的进度指示器,则始终需要扩展ProgressDialog类吗? 但是查看ProgressDialog类时,我没有发现除了常规可绘制对象(ProgressDialog.java)之外的任何内容,它们并未在其中使用AnimatedDrawable。

8个回答

104

我进行了一些测试,感觉实现这个最好的方法是使用自定义的对话框(Dialog)。

这里是我所做的一个示例。这将回答问题2,但会给你解决问题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);
    }
}

所有静态方法都来自这个链接,没有什么奇怪的地方,但是魔法发生在构造函数中。 请检查我传递的参数样式。那个样式如下:

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

这将导致一个ProgressBar在屏幕中心旋转。没有backgroundDim,也没有Dialog框。


1
@Macarse 不是...我也试过了:progressDialog = new MyProgressDialog(ItemListActivity.this); progressDialog.show(ItemListActivity.this, "title", "message"); progressDialog.dismiss(); 它可以正常显示,但无法关闭... - jul
3
我也遇到了无法关闭自定义对话框的问题,你们两个能否解释一下如何静态地调用它?谢谢。 - Millec8
7
请在声明样式时添加 parent。这个样式可能会在新的 APIs 中产生很多问题:parent="@android:style/Theme.Dialog" - Kostadin
4
为了关闭对话框,请执行以下操作: MyProgressDialog progressDialog; progressDialog = MyProgressDialog.show(ItemListActivity.this, "title", "message"); progressDialog.dismiss(); - Raoul George
1
我该如何设置样式,使得Spinner在ICS及以上版本中使用Holo.Light/Dark主题?目前Spinner使用的是旧版Gingerbread样式。尝试从parent="@android:style/Theme.Holo.Light.Dialog"或其他变体继承样式都无效。 - socoho
显示剩余21条评论

32

简单且可自定义的方法:

定义动画:(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%" />

或者:

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

接下来,定义布局:(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>

然后,实例进度对话框:

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

更多信息:


24
我使用以下内容,它不需要布局文件,并在屏幕中央放置一个居中、无边框的阻塞进度条。
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();
    }

}

1
确切地说,这正是我正在寻找的!谢谢 - Adnan Mulla
1
这仍然会根据您的主题添加白色背景。 - Sebastian Roth
我认为这是最简单的方法。真的做得很好,你节省了我很多时间! - Mattia Ruggiero
最简单的方法就是真的很短。 - Nut Tang
只有旋转器,这正是我一直在寻找的,回答得好 :) - Gustavo Baiocchi Costa

19

如果您只想显示不确定进度条。

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

创建一个名为 "progress_layout.xml" 的布局 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>

5

只需按照以下方法即可完成

在res->values->styles中添加以下代码

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

然后按照下面提到的步骤创建自己的ProgressDialog:

ProgressDialog dialog = new ProgressDialog(ctx, R.style.MyGravity);
dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);

谢谢,这对我来说是最好的答案。 - Hamid
此解决方案适用于大于21的API版本。 - Kwnstantinos Nikoloutsos

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

您可以在所有需要显示居中ProgressDialog的活动中添加一个ProgressBar。 在activity.xml中使用以下内容:

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

在你的Activity.java文件中,使用以下代码:
ProgressBar bar = new Progress();
bar = (ProgressBar) findViewById(R.id.progressBar);

现在,当您想要显示进度条时,只需将其可见性设置为visible,要取消,则将可见性设置为gone。
bar.setVisibility(View.VISIBLE);
bar.setVisibility(View.GONE);

-1

在我的情况下,使用ProgressBar并将其添加到LinearLayout中是这样的:

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


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接