Android ProgressBar:可见性不正常

问题描述

我无法理解 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();

如果有人能确认这是正确的方法,或者有更好的方法,我会很高兴。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...