问题描述
我无法理解 ProgressBar 的可见性是如何工作的。基本上我的 ProgressBar 在我需要时不会出现或消失。 我的代码太大,无法在此处显示所有内容,因此我创建了一个新的简单演示项目,并带有一个单击按钮:
fab.setonClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
Snackbar.make(view,"Replace with your own action",Snackbar.LENGTH_LONG)
.setAction("Action",null).show();
mProgressBar.setVisibility(View.VISIBLE);
SystemClock.sleep(1000);
mProgressBar.setVisibility(View.GONE);
SystemClock.sleep(1000);
mProgressBar.setVisibility(View.VISIBLE);
SystemClock.sleep(1000);
mProgressBar.setVisibility(View.GONE);
SystemClock.sleep(1000);
mProgressBar.setVisibility(View.VISIBLE);
}
}
mProgressBar = findViewById(R.id.progressbar);
mProgressBar.setVisibility(View.INVISIBLE);
我也试过几个版本的Progressbar;目前是这样的:
<ProgressBar
android:id="@+id/progressbar"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerVertical="true"
android:backgroundTint="@android:color/white"
android:gravity="center"
android:indeterminate="true"
android:indeterminateTint="#1a09d6"/>
所以,发生的情况是 ProgressBar 没有打开和关闭;它只是以最后一个状态结束。并且 SnackBar 也不会出现,直到所有睡眠之后。 如果我能理解如何让这个片段按我的意愿工作,那么我认为我的实际代码中会有一个解决(稍微复杂一些)的方法。 我已阅读其他线程并了解当主线程太忙时无法显示或更新 ProgressBar。我已经尝试过,正如其他人所建议的那样,使用
runOnUiThread(new Runnable() {
@Override
public void run() {
mProgressBar.setVisibility(View.GONE);
}
})
但这没什么区别。我也试过 View.Invalidate() 在可见性变化之间,但没有效果。我试过“INVISIBLE”而不是“GONE”。 显然,我在这里遗漏了一些关于任务和线程的基本知识!请帮忙。
解决方法
经过一些实验,我发现我做错了什么。虽然我的代码比这更复杂,但实际上我所做的是(在伪代码中):
show progress bar
start task
hide progress bar
所以结果并不令人意外,因为任务开始后栏就会隐藏。因此,progressBar 隐藏必须发生在任务类本身中。但是为了避免非静态类的潜在泄漏问题,需要活动“弱引用”:
public static class TaskTest extends AsyncTask<Void,Void,Void> {
private WeakReference<MainActivity> activityReference;
TaskTest(MainActivity context) {
activityReference = new WeakReference<>(context);
}
@Override
protected void onPreExecute()
{
activityReference.get().mProgressBar.setVisibility(View.VISIBLE);
super.onPreExecute();
}
@Override
protected Void doInBackground(Void... voids)
{
// do your stuff......shouldn't be more than a few seconds.
for (int i=0; i<4; i++)
{
SystemClock.sleep(1000);
}
return null;
}
protected void onPostExecute(Void result) {
activityReference.get().mProgressBar.setVisibility(View.GONE);
super.onPostExecute(result);
}
}
在主要活动中:
new TaskTest(MainActivity.this).execute();
如果有人能确认这是正确的方法,或者有更好的方法,我会很高兴。