• 10
name

A PHP Error was encountered

Severity: Notice

Message: Undefined index: userid

Filename: views/question.php

Line Number: 191

Backtrace:

File: /home/prodcxja/public_html/questions/application/views/question.php
Line: 191
Function: _error_handler

File: /home/prodcxja/public_html/questions/application/controllers/Questions.php
Line: 433
Function: view

File: /home/prodcxja/public_html/questions/index.php
Line: 315
Function: require_once

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.

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();
    } 
}
  • 47
Reply Report

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!

  • 16
Reply Report

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
    }
  • 10
Reply Report

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

  • 8
Reply Report

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/");
}
  • 7
Reply Report
    • To put it bluntly, I just spent around 6 hours trying to make this progress bar work and I've browsed through over 20 Q&A's here and everywhere else and this is, the only one, that seems to work on full screen webview. I love you for it. Thanks.

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();
    } 
}
  • 3
Reply Report
      • 2
    • I am extremely new to Android development, so this may be a silly question. What do I need to import in order to use BrowserActivity?
      • 1
    • @Nick, BrowserActivity is the current activity where you are implementing your code. It's the name of your activity.