How to use setProgressDrawable() correctly?

2020-08-14 07:35发布

问题:

I am having problem with setting a new Drawable to my ProgressBar.

If I use the setProgressDrawable() inside onCreate() method it works great. But when I try to call the same method inside a Handler post callback it doesn't work and the progressbar disapears.

Can someone explain this behaviour? How can I solve this problem?

回答1:

Bumped into this problem myself and I managed to get it working :)

I used the AsyncTask to handle the background tasks/threads, but the idea should be the same as using Runnable/Handler (though AsyncTask does feel nicer imo).

So, this is what I did... put setContentView(R.layout.my_screen); in the onPostExecute method! (ie. instead of the onCreate method)

So the code looks something like this:

public class MyScreen extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // setContentView(R.layout.my_screen); !!! Don't setContentView here... (see bottom)

    new MySpecialTask().execute();
}

private int somethingThatTakesALongTime() {
    int result;
    // blah blah blah
    return result;
}

private void updateTheUiWithResult(int result) {
    // Some code that changes the UI
    // For exampe:
    TextView myTextView = (TextView) findViewById(R.id.result_text);
    myTextView.setText("Result is: " + result);

    ProgressBar anyProgressBar = (ProgressBar) findViewById(R.id.custom_progressbar);
    anyProgressBar.setProgressDrawable(res.getDrawable(R.drawable.progressbar_style));
    anyProgressBar.setMax(100);
    anyProgressBar.setProgress(result);       
}

private class MySpecialTask extends AsyncTask<String, Void, Integer> {
    ProgressDialog mProgressDialog;

    @Override
    protected void onPreExecute() {
        mProgressDialog = ProgressDialog.show(MyScreen.this, "", "Calculating...\nPlease wait...", true);
    }
    @Override
    protected Integer doInBackground(String... strings) {
        return somethingThatTakesALongTime();
    }

    @Override
    protected void onPostExecute(Integer result) {
        mProgressDialog.dismiss();
        setContentView(R.layout.my_screen); // setContent view here... then it works...
        updateTheUiWithResult(result);
    }
}
}

To be honest, why you need to call setContentView in onPostExecute I have no idea... but doing so means you can set custom styles for your progress bars (and they don't disappear on you!)



回答2:

downloadingBar.setProgress(0); 

Drawable progressDrawable = getResources().getDrawable(R.drawable.download_progressbar_pause_bg);

progressDrawable.setBounds(downloadingBar.getProgressDrawable().getBounds()); 

downloadingBar.setProgressDrawable(progressDrawable); 

downloadingBar.setProgress(mCurrentPercent);  
  1. First you should reset the progress to zero
  2. Set the progress drawable bounds
  3. Set new progress drawable
  4. Set new progress


回答3:

Maybe you put the code in a thread which is not main thread. If you want to work with the UI, you must do that in the main thread :)



回答4:

I was also facing the same issue but in my case it is due to the use of Drawable.mutate() method. When i removed that method it started working fine. I also noticed that this issue exist below api level-21(lollipop).