34

我有一个 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"在应用程序清单中声明,进度条会不会再显示?

谢谢你。

4

6 回答 6

47

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

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();
    } 
}
于 2010-06-27T11:05:09.640 回答
16

我也遇到了同样的问题。

因为我设置了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);

C'est完成!

于 2011-03-22T06:48:45.610 回答
10

我已经解决了这个问题。

您的电话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
    }
于 2011-09-14T10:19:21.967 回答
8

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

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

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

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

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

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

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

于 2014-05-23T19:33:19.433 回答
7

看来,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允许进度条浮动在 webview 上方。设置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/");
}
于 2015-09-17T03:04:23.370 回答
3

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();
    } 
}
于 2010-06-22T11:39:30.057 回答