【问题标题】:Android: The progress bar in the window's title does not displayAndroid:窗口标题中的进度条不显示
【发布时间】:2011-03-06 18:11:32
【问题描述】:

我有一个 Web 视图来覆盖内置浏览器,我想在标题栏上显示一个进度指示器。

这是代码:

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    getWindow().requestFeature(Window.FEATURE_PROGRESS);

    setContentView(R.layout.browser);
    currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");

    try {
        mWebView = (WebView) findViewById(R.id.webview);
        mWebView.getSettings().setJavaScriptEnabled(true);
        mWebView.setWebViewClient(new browserActivityClient());
        setProgressBarIndeterminateVisibility(true);
        mWebView.loadUrl(currentURL);
        setProgressBarIndeterminateVisibility(false);
    } catch (Exception e) {
        Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
        Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
    } 
}

根据我在网上看到的 Android 文档和其他示例,我认为它应该可以工作。但它没有,你能告诉我我哪里错了吗?

还有一个问题:如果以后我会选择在应用程序清单中声明android:theme="@android:style/Theme.NoTitleBar",进度条会不会再显示?

谢谢。

【问题讨论】:

    标签: android progress-bar titlebar


    【解决方案1】:

    实际上正确的代码是(经过测试和工作的):

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        requestWindowFeature(Window.FEATURE_PROGRESS);
        currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");
    
        setContentView(R.layout.browser);
    
        setProgressBarIndeterminateVisibility(true);
        setProgressBarVisibility(true);
    
        try {
            mWebView = (WebView) findViewById(R.id.webview);
            mWebView.getSettings().setJavaScriptEnabled(true);
            mWebView.setWebViewClient(new browserActivityClient());
    
            mWebView.setWebChromeClient(new WebChromeClient() {
               public void onProgressChanged(WebView view, int progress) {
                   setProgress(progress * 100);
                  if(progress == 100) {
                     setProgressBarIndeterminateVisibility(false);
                     setProgressBarVisibility(false);
                  }
               }
            });
            mWebView.loadUrl(currentURL);
        } catch (Exception e) {
            Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
            Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
        } 
    }
    

    【讨论】:

    • 谢谢,这正是我想要的。
    • 完美运行,谢谢!请注意 requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);和 setProgressBarIndeterminateVisibility(true);在操作栏中设置微调器进度。
    • 所以看起来“更复杂的示例”的示例代码在developer.android.com/reference/android/webkit/WebView.html
    • 如果您使用activity.setProgress(progress * 100); 而不是activity.setProgress(progress * 1000);,则示例代码有效,因为setProgress 需要从0 到10000 的范围
    • progress range {0~100} setProgress range {0~10000} 所以我们乘以 100 得到完整范围
    【解决方案2】:

    我也遇到了同样的问题。

    因为我设置了 android:theme="@android:style/Theme.NoTitleBar"

    我通过在布局xml文件中添加ProgressBar来解决,如:

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"  
    android:orientation="vertical"  
    android:layout_width="fill_parent"  
    android:layout_height="fill_parent"  
    >
    
    <ProgressBar android:id="@+id/progressbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="fill_parent"
        android:layout_height="3px"
        android:max="100"
        android:visibility="gone"
    />
    
    <WebView   
        android:id="@+id/webview"  
        android:layout_width="fill_parent"  
        android:layout_height="fill_parent"  
    />  
    
    </LinearLayout>
    

    在代码中:

    //加载url时

    progressBar.setProgress(0);
    progressBar.setVisible(View.VISIBLE);
    

    ...

    //正在加载...进度已更改

    progressBar.setProgress(progress);
    

    ...

    // 页面结束时

    progressBar.setVisible(View.GONE);
    

    快结束了!

    【讨论】:

      【解决方案3】:

      我已经解决了这个问题。

      您对setProgressBarVisibility() 的调用必须在onStart()onResume() 中,因为在此之前,您似乎无法保证拥有任何可以更改可见性的视图。


      对于 Dralangus 这个令人难以置信的解决方案,这里有一些经过全面测试的生产代码。非常感谢你,德拉兰格斯!最后,一个在设备旋转时不会消失的微调器。

      public class MainActivity extends Activity
      {
      private static boolean showSpinner; // needs static
      
      public void spinnerOn()
          {
          showSpinner = true;
          setProgressBarIndeterminateVisibility(true);
          }
      
      public void spinnerOff()
          {
          showSpinner = false;
          setProgressBarIndeterminateVisibility(false);
          }
      
      protected void onResume()
          {
          // solved by Dralangus http://stackoverflow.com/a/7414659/294884
          super.onResume();
          if (showSpinner)
              {
              spinnerOn();
              }
          else
              {
              spinnerOff();
              }
          }
      
      protected void onStart()
          {
          super.onStart();
          // note, onResume is called EVEN LATER than onStart,
          // so your most reliable choice is onResume.
          // eternal thanks to Dralangus for this solution
          }
      
      @Override
      protected void onCreate(Bundle savedInstanceState)
          {
          super.onCreate(savedInstanceState);
          requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
      
          setContentView(R.layout.activity_main);
      
          ... // Your code
          }
      

      【讨论】:

      • 对于ListActivity,这是解决方案非常感谢
      【解决方案4】:

      看到一些答案如何混淆两个进度条,决定添加另一个答案

      这些用于顶部的水平进度条

      requestWindowFeature(Window.FEATURE_PROGRESS);
      setProgressBarIndeterminate(true);
      setProgress(intVal);
      setProgressBarVisibility(true);
      

      这些用于操作栏中的微调式进度条

      requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
      setProgressBarIndeterminateVisibility(true);
      

      您不需要同时请求两种窗口功能,只需要您需要的进度类型。

      OP 代码中的错误是调用 setProgressBarIndeterminateVisibility(true) 没有请求 Window.FEATURE_INDETERMINATE_PROGRESS(反之亦然:调用 setProgressBarIndeterminateVisibility() 而不是 setProgressBarVisibility()

      【讨论】:

        【解决方案5】:

        Android 5.0 (API 21) 及更高版本Windows.FEATURE_PROGRESS 似乎不再适用。从 univasity 的响应中得到一些提示,我能够构建一个类似于其他浏览器中的进度条。

        activity_main.xml"

        <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:context=".MainActivity"
        android:id="@+id/relativeLayout">
        
        <WebView
            android:layout_width="fill_parent"
            android:layout_height="fill_parent"
            android:id="@+id/webView" />
        
        <ProgressBar
            android:id="@+id/progressBar"
            style="?android:attr/progressBarStyleHorizontal"
            android:layout_width="fill_parent"
            android:layout_height="8dp"
            android:max="100"
            android:progressTint="#FF29A8FF"
            android:progressBackgroundTint="#FFFFFFFF"
            android:visibility="gone" />
        </FrameLayout>
        

        FrameLayout 允许进度条浮动在 web 视图上方。将android:max 设置为 100 使其与活动中的默认范围对齐,因此不必将值转换为默认值 0-10000,否则进度条会使用这些值。 android:visibility="gone" 默认使进度条不可见。

        MainActivty.java:

        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
        
            // Get the WebView and the ProgressBar from activity_main.xml.
            final WebView mainWebView = (WebView) findViewById(R.id.webView);
            final ProgressBar progressBar = (ProgressBar) findViewById(R.id.progressBar);
        
            // Enables JavaScript.
            mainWebView.getSettings().setJavaScriptEnabled(true);
        
            // Updates the progress bar whenever there are changes and hides it again when it completes.
            mainWebView.setWebChromeClient(new WebChromeClient() {
                public void onProgressChanged(WebView view, int progress) {
                    if (progress < 100) {
                            progressBar.setVisibility(View.VISIBLE);
                        } else {
                            progressBar.setVisibility(View.GONE);
                        }
                    progressBar.setProgress(progress);
                }
            });
        
            // Makes the mainWebView handle all URLs internally instead of calling the default browser.
            mainWebView.setWebViewClient(new WebViewClient());
        
            // Load a sample URL.
            mainWebView.loadUrl("http://developer.android.com/");
        }
        

        【讨论】:

        • 坦率地说,我只花了大约 6 个小时试图让这个进度条工作,我在这里和其他地方浏览了 20 多个问答,这是,唯一一个,这似乎适用于全屏 webview。我爱你。谢谢。
        【解决方案6】:

        WebView.loadUrl 在本机线程中运行,因此 setProgressBarIndeterminateVisibility(false) 几乎会立即被调用。此外,如果您使用 Theme.NoTitleBar,则不会显示标题栏,并且由于进度条位于标题栏中,因此也不会显示。

        这样的事情应该可以工作。

        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            getWindow().requestFeature(Window.FEATURE_PROGRESS);
        
            setContentView(R.layout.browser);
            currentURL = BrowserActivity.this.getIntent().getExtras().getString("currentURL");
        
            try {
                mWebView = (WebView) findViewById(R.id.webview);
                mWebView.getSettings().setJavaScriptEnabled(true);
                mWebView.setWebViewClient(new browserActivityClient());
                setProgressBarIndeterminateVisibility(true);
                mWebview.setWebChromeClient(new WebChromeClient() {
                   public void onProgressChanged(WebView view, int progress) {
                      if(progress == 100) {
                         setProgressBarIndeterminateVisibility(false);
                      }
                   }
                });
                mWebView.loadUrl(currentURL);
            } catch (Exception e) {
                Log.e(getClass().getSimpleName(), "Browser: " + e.getMessage());
                Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
            } 
        }
        

        【讨论】:

        • 我对 Android 开发非常陌生,所以这可能是一个愚蠢的问题。为了使用BrowserActivity,我需要导入什么?
        • @Nick,BrowserActivity 是您实现代码的当前活动。这是您的活动的名称。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多