Android: The progress bar in the window's title does not display

假如想象 提交于 2019-11-27 00:03:55

问题


I have a web view to override the built-in browser and I want to show a progress indicator on the title bar.

This is the code:

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

It should work, I think, according to Android docs and other samples I saw on the net. But it doesn't, could you please tell me where am I wrong?

And another question: if sometimes later I'll choose to declare android:theme="@android:style/Theme.NoTitleBar" in the application manifest, will the progress bar show anymore or not?

Thank you.


回答1:


In fact the correct code is (tested and working):

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



回答2:


I got the same problem too.

Because i set the android:theme="@android:style/Theme.NoTitleBar"

I solve it by add a ProgressBar in the layout xml file, such as:

<?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>

In code:

// when load url

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

...

// loading...progress changed

progressBar.setProgress(progress);

...

// when page finish

progressBar.setVisible(View.GONE);

C'est finish!




回答3:


I have solved the issue.

Your call to setProgressBarVisibility() must be in onStart() or onResume() because, before that point, it seems you are not guaranteed to have any view on which you can change a visibility.


For this incredible solution by Dralangus, here's some fully tested production code. Thank you so much, Dralangus! Finally, a spinner that does not go away upon device rotation.

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
    }



回答4:


Seeing how some answers mix up the two progress bars, decided to add another answer

These are for the horizontal progress bar at the top

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

these are for the spinner-style progress bar in the actionbar

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

You don't need to request both window features, just the one for the progress type you need.

The mistake in OP's code is caling setProgressBarIndeterminateVisibility(true) having not requested Window.FEATURE_INDETERMINATE_PROGRESS (or vice versa: calling setProgressBarIndeterminateVisibility() instead of setProgressBarVisibility())




回答5:


It appears that with Android 5.0 (API 21) and above Windows.FEATURE_PROGRESS no longer works. Taking some hints from the response by univasity, I was able to build a progress bar similar to those in other browsers.

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>

The FrameLayout allows the progress bar to float above the webview. Setting android:max to 100 makes it align with the default range in the activity, so the values don't have to be converted to the default of 0-10000 otherwise used by the progress bar. android:visibility="gone" makes the progress bar invisible by default.

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:


WebView.loadUrl is run in a native thread so setProgressBarIndeterminateVisibility(false) gets called immediately pretty much. Also if you use Theme.NoTitleBar the title bar will not be shown and since the progress bar is in the title bar it won't be shown either.

Something like this should work.

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


来源:https://stackoverflow.com/questions/3092291/android-the-progress-bar-in-the-windows-title-does-not-display

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!