问题
I'm trying to figure out how to fix the orientation problem on webview. Basically every time the user changes the orientation on the device the program goes white and reloads the entire page. This just takes to long.
I'd like it to work like every other program that simply adjusts the page size to fit the orientation.I've tried reading other articles on the subject, but when I implement their solution it doesn't seem to fix the problem.
Here is my current code.
package testdev.HelloWebApp;
import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class HelloWebAppActivity extends Activity {
/** Called when the activity is first created. */
private WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)findViewById(R.id.webView);
WebSettings webSettings =webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient (new HelloWebViewClient());
webView.loadUrl("http://google.com");
if (savedInstanceState != null)
((WebView)findViewById(R.id.webView)).restoreState(savedInstanceState);
}
private class HelloWebViewClient extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack())
{
webView.goBack();
return true;
}
return super.onKeyDown(keyCode, event);
}
@Override
protected void onSaveInstanceState(Bundle outState ){
((WebView) findViewById(R.id.webView)).saveState(outState);
}
}
回答1:
Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation. Thus, if you want to prevent runtime restarts due to orientation change when developing for API level 13 or higher (as declared by the minSdkVersion and targetSdkVersion attributes), you must include the "screenSize" value in addition to the "orientation" value. That is, you must decalare
<activity android:configChanges="orientation|screenSize">
Here's the docs: http://developer.android.com/guide/topics/resources/runtime-changes.html
回答2:
I had the same problem. The reason that the webView restarts when you flip the screen (in my case at least) is that you always initialize the webView when onCreate() runs, even though the webView is not null.
First add the following in your AndroidManifest.xml:
<activity android:configChanges="orientation">
Then, try adding an if-clause:
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Add this
if(webView == null){
webView = (WebView)findViewById(R.id.webView);
WebSettings webSettings =webView.getSettings();
webSettings.setJavaScriptEnabled(true);
webView.setWebViewClient (new HelloWebViewClient());
webView.loadUrl("http://google.com");
}
if (savedInstanceState != null)
((WebView)findViewById(R.id.webView)).restoreState(savedInstanceState);
}
...
回答3:
When you rotate the device, Android restarts the application to help reload the right configuration files. There are several ways to handle this. The main two are saving the state of the application and then reloading it after the configuration change, or telling Android not to reset the application for certain orientation changes. For your situation, I'd recommend the latter (because I've not worked much with the WebView). Here's how.
Add this to your Activity(s) manifest, that you do not want restarted.
< activity android:name=".MyActivity" android:configChanges="orientation" >
And if you want to execute any code on the configuration change, add this to your Activity's code.
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Do something here
}
回答4:
It is 2015, and many people are looking for a solution that still workds on Jellybean, KK and Lollipop phones. After much struggling I found a way to preserve the webview intact after you change orientation. My strategy is basically to store the webview in a separate static variable in another class. Then, if rotation occurs, I dettach the webview from the activity, wait for the orientation to finish, and reattach the webview back to the activity. For example... first put this on your MANIFEST (keyboardHidden and keyboard are optional):
<application
android:label="@string/app_name"
android:theme="@style/AppTheme"
android:name="com.myapp.abc.app">
<activity
android:name=".myRotatingActivity"
android:configChanges="keyboard|keyboardHidden|orientation">
</activity>
In a SEPARATE APPLICATION CLASS, put:
public class app extends Application {
public static WebView webview;
public static FrameLayout webviewPlaceholder;//will hold the webview
@Override
public void onCreate() {
super.onCreate();
//dont forget to put this on the manifest in order for this onCreate method to fire when the app starts: android:name="com.myapp.abc.app"
setFirstLaunch("true");
}
public static String isFirstLaunch(Context appContext, String s) {
try {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(appContext);
return prefs.getString("booting", "false");
}catch (Exception e) {
return "false";
}
}
public static void setFirstLaunch(Context aContext,String s) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(aContext);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("booting", s);
editor.commit();
}
}
In the ACTIVITY put:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(app.isFirstLaunch.equals("true"))) {
app.setFirstLaunch("false");
app.webview = new WebView(thisActivity);
initWebUI("www.mypage.url");
}
}
@Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
restoreWebview();
}
public void restoreWebview(){
app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
if(app.webviewPlaceholder.getParent()!=null&&((ViewGroup)app.webview.getParent())!=null) {
((ViewGroup) app.webview.getParent()).removeView(app.webview);
}
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT);
app.webview.setLayoutParams(params);
app.webviewPlaceholder.addView(app.webview);
app.needToRestoreWebview=false;
}
protected static void initWebUI(String url){
if(app.webviewPlaceholder==null);
app.webviewPlaceholder = (FrameLayout)thisActivity.findViewById(R.id.webviewplaceholder);
app.webview.getSettings().setJavaScriptEnabled(true); app.webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
app.webview.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT));
app.webview.getSettings().setSupportZoom(false);
app.webview.getSettings().setBuiltInZoomControls(true);
app.webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
app.webview.setScrollbarFadingEnabled(true);
app.webview.getSettings().setLoadsImagesAutomatically(true);
app.webview.loadUrl(url);
app.webview.setWebViewClient(new WebViewClient());
if((app.webview.getParent()!=null)){//&&(app.getBooting(thisActivity).equals("true"))) {
((ViewGroup) app.webview.getParent()).removeView(app.webview);
}
app.webviewPlaceholder.addView(app.webview);
}
Finally, the simple XML:
<RelativeLayout 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=".myRotatingActivity">
<FrameLayout
android:id="@+id/webviewplaceholder"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
</RelativeLayout>
There are several things that could be improved in my solution, but I already spent to much time, for example: a shorter way to validate if the Activity has been launched for the very first time instead of using SharedPreferences storage. This approach preserves you webview intact (afaik),its textboxes, labels, UI, javascript variables, and navigation states that are not reflected by the url.
来源:https://stackoverflow.com/questions/8640501/how-to-fix-rotation-on-webview-for-android-phones