The issue is the performance following rotation. The WebView has to reload the page, which can be a bit tedious.
What's the best way of handling an orientation change without reloading the page from source each time?
The issue is the performance following rotation. The WebView has to reload the page, which can be a bit tedious.
What's the best way of handling an orientation change without reloading the page from source each time?
If you do not want the WebView to reload on orientation changes simply override onConfigurationChanged in your Activity class:
@Override
public void onConfigurationChanged(Configuration newConfig){
super.onConfigurationChanged(newConfig);
}
And set the android:configChanges attribute in the manifest:
<activity android:name="..."
android:label="@string/appName"
android:configChanges="orientation|screenSize"
for more info see:
http://developer.android.com/guide/topics/resources/runtime-changes.html#HandlingTheChange
https://developer.android.com/reference/android/app/Activity.html#ConfigurationChanges
I've tried using onRetainNonConfigurationInstance (returning the WebView), then getting it back with getLastNonConfigurationInstance during onCreate and re-assigning it.
Doesn't seem to work just yet. I can't help but think I'm really close though! So far, I just get a blank/white-background WebView instead. Posting here in the hopes that someone can help push this one past the finish line.
Maybe I shouldn't be passing the WebView. Perhaps an object from within the WebView?
The other method I tried - not my favorite - is to set this in the activity:
android:configChanges="keyboardHidden|orientation"
... and then do pretty much nothing here:
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// We do nothing here. We're only handling this to keep orientation
// or keyboard hiding from causing the WebView activity to restart.
}
THAT works, but it might not be considered a best practice.
Meanwhile, I also have a single ImageView that I want to automagically update depending on the rotation. This turns out to be very easy. Under my res folder, I have drawable-land and drawable-port to hold landscape/portrait variations, then I use R.drawable.myimagename for the ImageView's source and Android "does the right thing" - yay!
... except when you watch for config changes, then it doesn't. :(
So I'm at odds. Use onRetainNonConfigurationInstance and the ImageView rotation works, but WebView persistence doesn't ... or use onConfigurationChanged and the WebView stays stable, but the ImageView doesn't update. What to do?
One last note: In my case, forcing orientation isn't an acceptable compromise. We really do want to gracefully support rotation. Kinda like how the Android Browser app does! ;)
Just write the following code lines in your Manifest file - nothing else. It really works:
<activity android:name=".YourActivity"
android:configChanges="orientation|screenSize"
android:label="@string/application_name">
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle state) {
super.onRestoreInstanceState(state);
}
These methods can be overridden on any activity, it just basically allows you to save and restore values each time an activity is created/destroyed, when the screen orientation changes the activity gets destroyed and recreated in the background, so therefore you could use these methods to temporary store/restore states during the change.
You should have a deeper look into the two following methods and see whether it fits your solution.
http://developer.android.com/reference/android/app/Activity.html
try this
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
private WebView wv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv = (WebView) findViewById(R.id.webView);
String url = "https://www.google.ps/";
if (savedInstanceState != null)
wv.restoreState(savedInstanceState);
else {
wv.setWebViewClient(new MyBrowser());
wv.getSettings().setLoadsImagesAutomatically(true);
wv.getSettings().setJavaScriptEnabled(true);
wv.setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);
wv.loadUrl(url);
}
}
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
wv.saveState(outState);
}
@Override
public void onBackPressed() {
if (wv.canGoBack())
wv.goBack();
else
super.onBackPressed();
}
private class MyBrowser extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
}
@Override
protected void onSaveInstanceState(Bundle outState )
{
super.onSaveInstanceState(outState);
webView.saveState(outState);
}
@Override
protected void onRestoreInstanceState(Bundle savedInstanceState)
{
super.onRestoreInstanceState(savedInstanceState);
webView.restoreState(savedInstanceState);
}