如何清除确定的重复进度条?

时间:2012-06-27 21:18:25

标签: android android-widget android-progressbar

我有一个Activity,其中包含一个启动长时间运行任务的按钮。我使用AsyncTask执行任务,并显示一个确定的ProgressBar,随着任务的进行而更新。第一次运行任务时一切正常,但在后续运行时会出现对话框,但已经是100%和100/100。我在我的Activity中覆盖了onCreateDialog和onPrepareDialog。我假设使用setProgress(0)会重置对话框,但这不起作用。我在AsyncTask的onPreExecute方法中使用showDialog,在AsyncTask的onPostExecute中使用dismissDialog。我能够让对话框重置的唯一方法是在onPostExecute中使用removeDialog,但我宁愿不重新创建对话框,因为我将重复使用几次。相关代码如下。这是API级别10。

@Override
protected Dialog onCreateDialog(int id) {
    switch (id) {
        case PROGRESS_DIALOG:
            progressDialog = new ProgressDialog(ProtoBufSerializationTestActivity.this);
            progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
            progressDialog.setCancelable(true);
            progressDialog.setMax(100);
            progressDialog.setMessage("Testing...");
            return progressDialog;
        default:
            return null;
    }
}

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
    super.onPrepareDialog(id, dialog);
    switch (id) {
        case PROGRESS_DIALOG:
            ProgressDialog tmp = (ProgressDialog)dialog;
            tmp.setProgress(0);
            tmp.setSecondaryProgress(0);
            return;
        default:
            Log.e("test", "Unknown dialog requested");
    }
}

private class SerializationTestTask extends AsyncTask<Void, Integer, Long> {

    @Override
    protected void onPreExecute() {
        showDialog(PROGRESS_DIALOG);
    }

    @Override
    protected Long doInBackground(Void... params) {
        long accumulator = 0;
        int totalSize = 0;
        for (int i = 0; i < 10000; i++) {
            final long start = System.nanoTime();
            //code to be timed
            final long end = System.nanoTime();
            accumulator += end - start;
            if (i % 100 == 0) {
                publishProgress(i);
            }
        }
        return accumulator;
    }

    @Override
    protected void onPostExecute(Long aLong) {
        dismissDialog(PROGRESS_DIALOG);
        results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong / 1e10));
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        progressDialog.incrementProgressBy(1);
    }

编辑在接受@ Arhimed的建议后,我最终得到了以下代码。它简单得多。我可以使用DialogFragment,但在这种情况下我认为没有必要。

private class SerializationTestTask extends AsyncTask<Void, Integer, Long> {
    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {
        dialog = ProgressDialog.show(ProtoBufSerializationTestActivity.this, "Serialization Test", "Testing...", false);
    }

    @Override
    protected Long doInBackground(Void... params) {
        long accumulator = 0;
        int totalSize = 0;
        for (int i = 0; i < 10000; i++) {
            final long start = System.nanoTime();
            //code to be timed
            final long end = System.nanoTime();
            accumulator += end - start;
            if (i % 100 == 0) {
                publishProgress(i);
            }
        }
        return accumulator;
    }

    @Override
    protected void onPostExecute(Long aLong) {
        dialog.dismiss();
        results.setText(String.format("Serialized Message 10000 times.\nAverage time to serialize %.3fms", (double) aLong / 1e10));
    }

    @Override
    protected void onProgressUpdate(Integer... values) {
        dialog.incrementProgressBy(1);
    }
}

3 个答案:

答案 0 :(得分:2)

实际上Arhimed是对的,你不能这样做,但你可以强迫进度条以“脏”的方式进入零状态。对我来说,客户希望进度条将其值归零,无论如何,以防万一用户离开了那个活动,但在我的情况下,进度仍然存在,并且只是从开始重新开始。我有自定义进度可绘制而且setProgress根本没有帮助我。所以我做的是之前调用此方法实际上设置REAL drawable setProgressDrawable(null)这是脏的方式清除,但它做你想要的,然后只用自己的progressdrawable调用相同的方法,所以感觉就像它已经刷新。说它..没有其他方式你不幸的是,可以实现这一目标。

答案 1 :(得分:1)

以这种方式使用ProgressDialog是不可能的。您的AsyncTask每次都应创建一个新实例。

答案 2 :(得分:0)

实际上,只有进度开始时,setProgress(0)才会刷新显示。 因此,您可以通过在setProgress之前调用onStart来强制刷新,如下所示:

@Override
protected void onPrepareDialog(int id, Dialog dialog) {
    super.onPrepareDialog(id, dialog);
    ProgressDialog progress = (ProgressDialog)dialog;
    progress.onStart();
    progress.setProgress(0);
}