【问题标题】:View's Visibility change don't work well programatically视图可见性更改不能以编程方式正常工作
【发布时间】:2016-10-18 06:57:48
【问题描述】:

我正在尝试在我的活动中添加一个进度条。在布局 XML 文件中,我为 progressBar 和 textView 设置了 android:visibility="gone" 来显示进度级别。我想按下一个按钮并使用 progressBar 和 textview visibility="visible" 启动一个进程,然后在进程结束后再次隐藏它们。

这是我的按钮代码。

问题是当我按下发现按钮时,什么都没有显示!!! 当我删除 Log.e("visibilty","GONE") 之前的两行时,视图仅在进程结束后才可见。似乎 setVisibility 指令是在 While 循环之后执行的,这太奇怪了。

有什么解决办法吗?

【问题讨论】:

  • 请不要以图片形式发布您的代码。始终将其复制到问题本身中。如果您担心保持代码格式,请查看 StackOverflow 的 Markdown 规则 here

标签: android android-view visibility


【解决方案1】:

您正在尝试在主 UI 线程中修改 UI,但存在延迟。这不会按预期工作。您可以使用 AsyncTask 来更新视图并在最后隐藏它。

private class Sample extends AsyncTask<String, Void, String> {

    @Override
    protected String doInBackground(String... params) {
        //Do in background, NO UI HERE
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(1000);
                this.publishProgress(); //Call onProgressUpdate
            } catch (InterruptedException e) {
                Thread.interrupted();
            }
        }
        return "Finished!";
    }

    @Override
    protected void onPostExecute(String result) {
        //After it's completed, touch UI here
    }

    @Override
    protected void onPreExecute() {
       //Before it starts, touch UI here
    }

    @Override
    protected void onProgressUpdate(Void... values) {
        //Update text here, touch UI here
    }
}

【讨论】:

  • 我不会走那么远。一个 Handler 应该是所有 OP 的需要。
  • 同意他的特殊情况可能有点矫枉过正
  • 谢谢。它工作得很好,我是这样做的:discover.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Sample task = new Sample(); task.onPreExecute(); task.doInBackground( ); } });但它不处理 onPostExecute() 方法。因此,进度条和 textView 在进程结束后仍然可见。有什么线索可以解决这个问题吗?
  • 你不要直接这样调用方法,你会在任务上调用execute
【解决方案2】:

如果你想在延迟后运行一些代码,你可以使用 Handler+Runnable 而不是休眠主线程。

final Handler handler = new Handler();
Runnable hideRunnable = new Runnable() {
  @Override
  public void run() {
    // Your visibility logic
  }
};  
handler.postDelayed(hideRunnable, 190); // 190 milliseconds

有一些关于Updating a ProgressBar with a Handler的讨论。如果你确实需要一些进度跟踪,AsyncTask 确实有内置的。

【讨论】:

  • 谢谢!我已经尝试过这个解决方案,但是经过一段时间的处理后,它给我带来了一个致命错误:android.view.ViewRootImpl$CalledFromWrongThreadException: 只有创建视图层次结构的原始线程才能触摸它的视图。
  • 这就是我放弃 handler/Runnable 解决方案并使用经典的 While 循环和 thread.sleep 指令切换到主线程的原因。
  • 哦,那么您需要在 Runnable 中添加一个 runOnUiThread。无论如何,绝对不要让主线程休眠。
猜你喜欢
  • 2013-03-09
  • 1970-01-01
  • 2021-09-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-23
  • 2011-03-28
  • 1970-01-01
相关资源
最近更新 更多