Android: The progress bar in the window's title does not display
I have a web view to override the built-in browser and I want to show a progress indicator on the title b开发者_如何学Car.
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();
}
}
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!
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
}
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()
)
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/");
}
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();
}
}
精彩评论