Android如何更新ProgressBar的值?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11409912/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 07:18:19  来源:igfitidea点击:

Android how to update value of ProgressBar?

androidprogress-bar

提问by user1417127

My activity have a ProgressBar. When start activity, I'll check value get from another place and update to ProgressBar. Here's my code:

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

Value of ProgressBar i get from int value = Downloader.progress.get(gameId)and it's correct. But when I run this code, the activity is not responding and not showing anything (but app not crash). Seems like the thread to update ProgressBar running and block the UI thread so the activity layout is not showing.

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

What's wrong with my code? What is the correct way to update ProgressBar in this situation?

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

回答by Luis

You are running a while (progressBar.getProgress() < 100)in the UI thread (you use runOnUiThread) so UI thread will be blocked (and nothing painted) until this loop finish.

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

You can:

你可以:

  • Put the runOnUiThreadinside the loop and, maybe, a sleep inside de runOnUiThreadcall. However, it is not the preferred kind of solution since you are using too much CPU to just look for a value change. The sleep approach it a bit ugly but solves the cpu problem. It would be something like::

    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);
            }
        });
      }
    };
    
  • Update the progress bar in an event way so you only call (in the UI thread) the update code when progress changes. It is the preferred way.

  • runOnUiThread里面的循环,也许,在 de runOnUiThreadcall里面睡觉。但是,这不是首选的解决方案,因为您使用过多的 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 线程中)更新代码。这是首选方式。

回答by AkashG

Try with:

尝试:

    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) {
        }
    }

Declare progressEnable globally:

全局声明progressEnable:

private boolean progressEnable=true;

回答by psykid

I usually use this code:

我通常使用这个代码:

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

Hope this helps

希望这可以帮助

回答by lookashc

You can auto-advance progress bar using RXJava.

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