【问题标题】:Android ProgressBar: visibility not behavingAndroid ProgressBar:可见性不正常
【发布时间】:2020-12-29 20:48:07
【问题描述】:

我无法理解 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
    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 也不会出现,直到所有的睡眠之后。 如果我能理解如何让这个 sn-p 按我的意愿工作,那么我认为在我的实际代码中会有一个解决方案(稍微复杂一点)。 我已阅读其他线程并了解在主线程太忙时无法显示或更新 ProgressBar。正如其他人所建议的那样,我尝试过使用

runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    mProgressBar.setVisibility(View.GONE);
                }
            })

但这没有区别。我也试过 View.Invalidate() 在可见性变化之间,但没有效果。而且我尝试过“INVISIBLE”而不是“GONE”。 显然,我在这里遗漏了一些关于任务和线程的基本知识!请帮忙。

【问题讨论】:

  • 你使用 runOnUiThread 错误...应该从其他线程使用..
  • 它为什么不工作也很明显......你在 onClick 中阻塞了主线程,所以没有其他主线程工作完成(fx 重绘 - 没有重绘 - 没有视觉变化)
  • 好吧,你说我“阻塞了主线程”,但这是一个由 Android Studio 创建的开箱即用的新项目。所以你的评论对新手来说帮助不大!我现在已将计时器代码移动到异步任务中,并且 ProgressBar 出现了,谢谢。但这会产生一个新问题(“异步任务应该是静态的”),其他人似乎不同意如何处理:link。仅仅为了显示一个简单的进度条就做了很多工作!
  • 在我的“真实”代码中,密集的工作在异步任务中完成的,但我仍然无法让 ProgresBar 正确显示。现在意识到在完成文件查找意图后,一项任务是从“onActivityResult()”开始的。在这种情况下,使用 'runOnUiThread() 方法已经解决了。

标签: android android-progressbar


【解决方案1】:

经过一些实验,我发现我做错了什么。虽然我的代码比这更复杂,但实际上我所做的是(在伪代码中):

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

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

【讨论】:

    猜你喜欢
    • 2017-08-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-03
    • 1970-01-01
    • 1970-01-01
    • 2021-10-21
    相关资源
    最近更新 更多