Android change ProgressDialog drawable while dialog works
Asked Answered
K

2

7

I have a ProgressDialog which i started when Activity is Created(insideOnCreate method).

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

After 2500ms i want to change a circle animation to my custom image(see below) (like an a simulation about when i finish retrieve some data from server and i'm done.) So i need to show user that process is finished. For this goal i select a next way.

  1. I show dialog
  2. When i retrieve data i change drawable of ProgressDialog

And this i have a problem. When i set the first time a 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 change drawable and all looks ok. But when ProgressBar launched(worked/circle animation playing) i try to reset a drawable

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

And i have unexpected result : circle animation disappear and no image set to current progress drawable. NO IMAGE! BLANK AREA instead of my image.

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

So my question is - how i can change drawable in runtime during ProgressDialog works?

enter image description here need to be changed to enter image description here

Kreutzer answered 20/3, 2015 at 16:49 Comment(0)
K
7

Finally i find a solution

ProgressDialog contains inside a ProgressBar which display our drawable.

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

When we try to set drawable again to ProgressDialog,ProgressDialog really set a new drawable. But this drawable didn't have a bounds (coordinates to display this view).
So we must set it hardly. I choose a copy way - just a copy bounds from current drawable of ProgressDialog. You can use another way.

Initialize dialog :

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

Show

    mProgressDialog.show();

Change drawable

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.");
}

Note :

Solution untested on specific cases like an

  • We have a progress bar in ActionBar/TitleBar
  • Another cases when we already have an android.R.progress on the screen window. In this case i think my solution will be produce unexpected behavior.
Kreutzer answered 20/3, 2015 at 18:4 Comment(1)
bar.getIndeterminateDrawable method doesn't exist in ProgressBar class though in 2020 android studio 3.7. I just had to set an arbitrary bounds. But ProgressBar is so good - Google shouldn't deprecate it. In iOS had to use a library but, ProgressBar is good in Android.Psychologize
C
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);

For first time call with initDialog(false);

As far as I checked indeterminate drawable cannot really be replaced, so this workaround can save you from creating custom ProgressBar.

Cords answered 20/3, 2015 at 17:11 Comment(2)
Yes. It works, But it's blinked because we show a new instance of ProgressDialogKreutzer
yes, I faced same situation had two options either use this one or create a custom ProgressBar.Cords

© 2022 - 2024 — McMap. All rights reserved.