【问题标题】:Android change ProgressDialog drawable while dialog worksAndroid在对话框工作时更改ProgressDialog drawable
【发布时间】:2015-03-20 16:49:12
【问题描述】:

我有一个 ProgressDialog,它是在创建 Activity 时启动的(insideOnCreate 方法)。

private void initDialog() {
    mProgressDialog = new ProgressDialog(this);
    mProgressDialog.setIndeterminate(true);
    mProgressDialog.setTitle("Please wait.");
    mProgressDialog.setMessage("Connecting to LinkedIn.");
    mProgressDialog.setCancelable(false);
    mProgressDialog.show();
}

2500 毫秒后 我想将圆形动画更改为我的自定义图像(见下文)(就像我完成从服务器检索一些数据并完成时的模拟。)所以我需要向用户显示该过程已完成。为了这个目标,我选择了下一条路。

  1. 我显示对话框
  2. 当我检索数据时,我会更改 ProgressDialog 的可绘制对象

我有一个问题。当我第一次设置drawable时

private void initDialog() {
    mProgressDialog = new ProgressDialog(this);
    mProgressDialog.setIndeterminate(true);
    mProgressDialog.setTitle("Please wait.");
    mProgressDialog.setMessage("Connecting to LinkedIn.");
    mProgressDialog.setCancelable(false);
    //This
    mProgressDialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.ok));
    mProgressDialog.show();
}

ProgressDialog 更改可绘制对象,一切正常。但是当 ProgressBar 启动(工作/圆形动画播放)时,我尝试重置可绘制对象

mProgressDialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.ok));

我得到了意想不到的结果:圆形动画消失并且没有图像设置为当前进度可绘制。没有图像!空白区域而不是我的图像。

    authButton.postDelayed(new Runnable() {
        @Override
        public void run() {
            mProgressDialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.ok)); //doesn't work as expected!
        }
    }, 2500);

所以我的问题是 - 在 ProgressDialog 工作期间如何在运行时更改可绘制对象?

需要改成

【问题讨论】:

  • 有趣的问题:)

标签: android progressdialog


【解决方案1】:

终于找到了解决办法

ProgressDialog 包含在 ProgressBar 中,它显示了我们的可绘制对象。

View view = inflater.inflate(a.getResourceId(com.android.internal.R.styleable.AlertDialog_horizontalProgressLayout, R.layout.alert_dialog_progress), null);
mProgress = (ProgressBar) view.findViewById(R.id.progress); // THIS
mProgressNumber = (TextView) view.findViewById(R.id.progress_number);
mProgressPercent = (TextView) view.findViewById(R.id.progress_percent);
setView(view);

当我们再次尝试将drawable设置为ProgressDialog时,ProgressDialog 真的设置了一个新的drawable但是这个drawable没有边界(显示这个视图的坐标)。
所以我们必须很难设置它。我选择了一种复制方式——只是从ProgressDialog的当前drawable中复制边界。您可以使用其他方式。

初始化对话框:

private void initDialog() {
    mProgressDialog = new ProgressDialog(this);
    mProgressDialog.setIndeterminate(true);
    mProgressDialog.setTitle("Please wait.");
    mProgressDialog.setMessage("Connecting to LinkedIn.");
    mProgressDialog.setCancelable(false);
}

显示

    mProgressDialog.show();

更改可绘制对象

private void changeToDone(int resId) {
    //Getting a progressBar from dialog
    ProgressBar bar = (ProgressBar) mProgressDialog.findViewById(android.R.id.progress);
    //Getting a DONE(new) drawable from resources
    Drawable drawable = getResources().getDrawable(resId);
    //Getting a drawable from progress dialog
    Drawable indeterminateDrawable = bar.getIndeterminateDrawable();
    //Obtain a bounds of current drawable
    Rect bounds = indeterminateDrawable.getBounds();
    //Set bounds to DONE(new) drawable
    drawable.setBounds(bounds);
    //Set a new drawable
    bar.setIndeterminateDrawable(drawable);

    mProgressDialog.setTitle("Done.");
    mProgressDialog.setMessage("Connected.");
}

注意:

解决方案未经测试,例如

  • 我们在ActionBar/TitleBar有一个进度条
  • 另一种情况是我们在屏幕窗口上已经有一个android.R.progress。在这种情况下,我认为我的解决方案会产生意想不到的行为。

【讨论】:

  • bar.getIndeterminateDrawable 方法在 ProgressBar 类中不存在,但在 2020 android studio 3.7 中。我只需要设置一个任意界限。但是 ProgressBar 非常好 - 谷歌不应该弃用它。在 iOS 中必须使用库,但 ProgressBar 在 Android 中很好。
【解决方案2】:
private void initDialog(boolean is) {
    mProgressDialog = new ProgressDialog(this);
    mProgressDialog.setIndeterminate(true);
    mProgressDialog.setTitle("Please wait.");
    mProgressDialog.setMessage("Connecting to LinkedIn.");
    mProgressDialog.setCancelable(false);
    if(is) // take global variable
    mProgressDialog.setIndeterminateDrawable(getResources().getDrawable(R.drawable.ic_launcher));
    mProgressDialog.show();
    if(!is)
    new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            mProgressDialog.cancel();
            mProgressDialog = null;
            initDialog(true);   
        }
    }, 2500);

第一次拨打initDialog(false);

据我检查,无法真正替换不确定的可绘制对象,因此此解决方法可以让您免于创建自定义 ProgressBar。

【讨论】:

  • 是的。它可以工作,但它会闪烁,因为我们显示了ProgressDialog 的新instance
  • 是的,我遇到了同样的情况,有两个选择,要么使用这个,要么创建一个自定义 ProgressBar。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 1970-01-01
相关资源
最近更新 更多