如何让ProgressBar更顺畅地显示进度?
目前我正在使用此功能(它以秒为单位计算特定时间,在此示例中为secondsToRun = 120
):
public void startBrushing(View view) {
progressBar = (ProgressBar) findViewById(R.id.progressBar);
int secondsToRun = 120;
progressBar.setMax(secondsToRun);
runner = new AsyncTaskRunner();
runner.execute(secondsToRun);
}
private class AsyncTaskRunner extends AsyncTask<Integer, Integer, Void> {
private String resp;
@Override
protected Void doInBackground(Integer... params) {
try {
for(int i = 0; i <= params[0]; i++) {
publishProgress(i);
Thread.sleep(1000);
if (i == params[0]) {
Log.d("CyCy", "Finished Countdown!");
chronometer.stop();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Integer... status) {
progressBar.setProgress(status[0]);
}
}
如果我增加更新时间(secondsToRun = 1200
并每隔100毫秒更新一次而不是每1000毫秒更新一次)它也可以正常工作但它有点不准确。
如果我使用secondsToRun = 12000
并每隔10毫秒更新一次,则非常不准确。循环说&#34; 30秒结束&#34;实时是37秒。
感谢您的帮助,抱歉我的英语不好。
答案 0 :(得分:1)
正如我在上面的评论中所建议的那样,您可以根据实时而非自己的计数器更新ProgressBar:
我没有对此进行测试,因此将其视为温和的伪代码:
private class AsyncTaskRunner extends AsyncTask<Void, Long, Void> {
private long startTime;
private long progressDurationMillis;
private long updateFrequencyMillis = 200; // default 0.2 secs
// pass in the progress bar max duration in the constructor
// so you can set the dialog max value in onPreExecute()
public AsyncTaskRunner(long progressDurationMillis) {
this.progressDurationMillis = progressDurationMillis;
}
// a second constructor for easy testing of different update values
// you could test a bunch together in a loop and see which looks best
public AsyncTaskRunner(long progressDurationMillis, long updateFrequencyMillis) {
this(progressDurationMillis);
this.updateFrequencyMillis = updateFrequencyMillis;
}
@Override
public void onPreExecute() {
this.startTime = System.getCurrentMillis();
// set up your dialog here and display
}
@Override
protected Void doInBackground(Void... params) {
long timeExpired = 0;
try {
while(true) {
timeExpired = progressDurationMillis - (System.getCurrentMillis() - startTime)
publishProgress(timeExpired);
Thread.sleep(updateFrequencyMillis);
if (timeExpired >= progressDurationMillis) {
Log.d("CyCy", "Finished Countdown!");
chronometer.stop();
// exit the while loop
break;
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onProgressUpdate(Long... status) {
progressBar.setProgress(status[0]);
}
@Override
public void onPostExecute() {
// dismiss your dialog here
}
}
答案 1 :(得分:1)
int msecondsToRun = 120 * 1000 // If it should run 2 minutes.
startCountdown(msecondsToRun);
private void startCountdown(final long countdownTime) {
countDownTimer = new CountDownTimer(countdownTime, 10) {
// The millisUntilFinished thing is for a "pausing" function I implemented.
public void onTick(long millisUntilFinished) {
timerProgress = msecondsToRun - millisUntilFinished;
progressBar.setProgress((int) timerProgress);
}
public void onFinish() {
// For styling purposes because of the "inaccuracy" of the timer
// so the progress will be shown as "full"
progressBar.setProgress((int) msecondsToRun);
}
}.start();
}
如果您有任何问题或提示,请随时发表评论!