Android:进度条未显示中间状态

时间:2015-08-30 14:17:11

标签: android multithreading progress-bar

还有其他类似的SO问题,但没有一个真正有用。

我只想实现一个进度条,按钮点击,从0开始,逐渐移动并停在一个点(从sharedPreferences读取)。

然而事情正在发挥作用,但进度条没有逐步更新,而是直接显示在终点。

我在这里粘贴的简化代码:

public class MainActivity extends ActionBarActivity {

int primaryProgress = 0;
int finalPrimaryProgress = 60;
ProgressBar progressBar;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    progressBar = (ProgressBar) findViewById(R.id.progress_bar);
    progressBar.setMax(100);
    progressBar.setProgress(0);
}

public void click(View view) {

    while (primaryProgress < finalPrimaryProgress)
    {
        progressBar.setProgress(primaryProgress+=1);
        Thread.sleep(100); //This is inside Try-catch in actual code.
    }
}
}

我知道问题出在线程上,但我对线程不太友好,所以无法理解这个问题。

1 个答案:

答案 0 :(得分:1)

我假设你的&#34;点击&#34;方法正在UI线程上发生(否则,当您尝试在后台线程上更改视图时,您可能会遇到异常)。

想想你在这里做了什么 - 当你点击一个按钮时,你开始循环。在循环的每次迭代中,您更改进度条的值,然后使(主)线程休眠100毫秒,然后重复。

问题是,您永远不会让运行时对您所做的更改做出反应。一旦更改了视图的值(例如,更改TextView的文本),Android运行时需要有时间对您的更改做出反应,调整视图的大小,位置然后重绘。在您再次更改值之前,您的代码基本上阻止了任何事情发生,因为您告诉主线程要休眠,然后您立即再次更改该值。

这里的预期结果是,一旦你停止更改其值而不让运行时实际上对它做任何事情,就会看到在最终状态下绘制的进度条。

作为当前点击方法的替代方法,请尝试使用postDelayed执行某些操作。这将允许运行时在每次迭代之间执行完整的度量 - 布局 - 绘制循环:

private void increaseProgressBar()
{
    if (progressBar.getProgress() < progressBar.getMax())
        progressBar.postDelayed(new Runnable() {

            @Override
            public void run() {
                progressBar.setProgress(progressBar.getProgress() + 1); // increase the value of the progress bar.
                increaseProgressBar(); // call the function again, but after a delay.
            }
        }, 100);
}

public void click(View v)
{
    increaseProgressBar();
}

注意:请记住,目前,多次单击该按钮会导致行为不稳定,因为您基本上会向此序列添加额外的可运行,从而导致进度条增长得更快。你可以用一个简单的旗帜轻松地防范这种情况。