【问题标题】:Android how to update value of ProgressBar?Android如何更新ProgressBar的值?
【发布时间】:2012-07-10 08:59:54
【问题描述】:

我的活动有一个 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();

我从int value = Downloader.progress.get(gameId) 获得的 ProgressBar 的值是正确的。但是当我运行此代码时,活动没有响应并且没有显示任何内容(但应用程序没有崩溃)。似乎更新 ProgressBar 的线程正在运行并阻塞 UI 线程,因此活动布局不显示。

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

【问题讨论】:

标签: android progress-bar


【解决方案1】:

您正在 UI 线程中运行 while (progressBar.getProgress() &lt; 100)(您使用 runOnUiThread),因此 UI 线程将被阻塞(并且不绘制任何内容)直到此循环完成。

你可以:

  • runOnUiThread 放入循环中,也许,在runOnUiThread 调用中加入睡眠。但是,它不是首选的解决方案,因为您使用过多的 CPU 来查找值更改。 sleep 方法有点难看,但解决了 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 线程中)调用更新代码。这是首选方式。

【讨论】:

  • 如何以事件的方式更新进度条?你能说得更具体一点吗?
  • 谢谢。您对 UI 线程内的循环是正确的。由于我的应用程序运行速度非常慢,因此您使用过多的 CPU 也是正确的。你能告诉我如何以事件的方式更新进度条吗?
  • 不确定下载器的作用。它可能有一个 ondownload 事件(或类似的东西),您可以在其中提交一个对progressBar 进行更新的侦听器。如果没有,你可以采取一点丑陋的睡眠方法。让我编辑我的答案以放置 if 的示例
【解决方案2】:

尝试:

    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;

【讨论】:

    【解决方案3】:

    我通常使用这个代码:

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

    希望对你有帮助

    【讨论】:

      【解决方案4】:

      您可以使用 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();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-05-14
        • 2017-08-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-24
        • 2011-02-13
        相关资源
        最近更新 更多