Android如何更新ProgressBar的值?

时间:2012-07-10 08:59:55

标签: android progress-bar

我的活动有一个ProgressBar。启动活动时,我会检查从其他地方获取的值并更新到ProgressBar。这是我的代码:

final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar_detail);
final TextView progressText = (TextView) findViewById(R.id.progressText_detail);
final ImageView btnCancel = (ImageView) findViewById(R.id.imgCancel_detail);
progressBar.setVisibility(View.VISIBLE);
progressText.setVisibility(View.VISIBLE);
btnCancel.setVisibility(View.VISIBLE);
Thread t = new Thread() {
    public void run() {
        ((Activity) ctx).runOnUiThread(new Runnable() {
            public void run() {
                int oldProgress = 0;
                while (progressBar.getProgress() < 100) {
                    int value = Downloader.progress.get(gameId+ "");
                    if (value != oldProgress) {
                        oldProgress = value;
                        progressBar.setProgress(value);
                        progressText.setText(value + " %");
                    }
                }
            }
        });
    }
};
t.start();

ProgressBar的价值我来自int value = Downloader.progress.get(gameId)并且它是正确的。但是,当我运行此代码时,活动没有响应,也没有显示任何内容(但应用程序没有崩溃)。看起来像更新ProgressBar的线程正在运行并阻止UI线程,因此活动布局没有显示。

我的代码出了什么问题?在这种情况下更新ProgressBar的正确方法是什么?

4 个答案:

答案 0 :(得分:12)

您正在UI线程中运行while (progressBar.getProgress() < 100)(使用runOnUiThread),因此在此循环完成之前,UI线程将被阻止(并且不会被绘制)。

你可以:

  • runOnUiThread放入循环中,或许可以在de runOnUiThread调用中进行睡眠。但是,它不是首选的解决方案,因为您使用太多CPU来查找值更改。睡眠接近它有点难看但解决了cpu问题。它会像::

    Thread t = new Thread() {
        public void run() {
        int oldProgress = 0;
    
        while (progressBar.getProgress() < 100) {
                ((Activity) ctx).runOnUiThread(new Runnable() {
                    public void run() {
                        int value = Downloader.progress.get(gameId+ "");
                        if (value != oldProgress) {
                            oldProgress = value;
                            progressBar.setProgress(value);
                            progressText.setText(value + " %");
                        }
                    }
                }
                Thread.sleep(500);
            }
        });
      }
    };
    
  • 以事件方式更新进度条,以便在进度更改时仅调用(在UI线程中)更新代码。这是首选方式。

答案 1 :(得分:1)

尝试:

    int currentPosition=0;
    int total=mediaPlayer.getDuration();
    while(mediaPlayer!=null && currentPosition<total){
        try{
            if(progressEnable){
                Thread.sleep(1000);
                currentPosition=mediaPlayer.getCurrentPosition();
                long pos=1000L * currentPosition/total;
                Log.d("thread pos", pos+"");
                progressSeekBar.setProgress((int) pos);
            }
        }
        catch (Exception e) {
        }
    }

全局声明progressEnable:

private boolean progressEnable=true;

答案 2 :(得分:0)

我通常使用此代码:

private int mProgressStatus;
private Handler mHandler = new Handler();

public void startProgress(View view) {
    final ProgressBar progressBar = (ProgressBar) findViewById(R.id.horizontal_progress);
    mProgressStatus = 0;
    progressBar.setProgress(mProgressStatus);

    //progressBar.setVisibility(View.VISIBLE);
    new AsyncTask<Void, Void, Void>() {
        @Override
        protected Void doInBackground(final Void... params) {
            while (mProgressStatus < 100) {
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                mProgressStatus += 15;
                mHandler.post(new Runnable() {
                    public void run() {
                        progressBar.setProgress(mProgressStatus);
                    }
                });
            }
            return null;
        }

    }.execute();
}

希望这有帮助

答案 3 :(得分:0)

您可以使用RXJava自动提升进度条。

@Override
protected void onAttachedToWindow() {
    super.onAttachedToWindow();
    if (autoProgress) {
        autoProgressSubscriber = Observable.interval(0, 1000/60, TimeUnit.MILLISECONDS) //~60fps
                    .map(index -> calculateAutoProgress())
                    .subscribe(progress -> {
                        if (progressBar != null) {
                            progressBar.setProgress(progress);
                        }
                    });
    }
}

@Override
protected void onDetachedFromWindow() {
    if (autoProgress) {
        autoProgressSubscriber.unsubscribe();
    }
    super.onDetachedFromWindow();
}