如何修复Android手机的webview旋转?

时间:2011-12-27 01:50:58

标签: android webview screen orientation

我正在试图弄清楚如何修复webview上的方向问题。基本上每次用户更改设备上的方向时,程序都会变白并重新加载整个页面。这只需要很长时间。

我希望它像所有其他程序一样,只是调整页面大小以适应方向。我已经尝试阅读有关该主题的其他文章,但是当我实施他们的解决方案时,它似乎没有修复问题

这是我目前的代码。

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

4 个答案:

答案 0 :(得分:7)

从Android 3.2(API级别13)开始,当设备在纵向和横向之间切换时,“屏幕尺寸”也会发生变化。因此,如果要在开发API级别13或更高级别(由minSdkVersion和targetSdkVersion属性声明)时由于方向更改而阻止运行时重新启动,则除了“orientation”值之外,还必须包含“screenSize”值。也就是说,你必须转发

<activity android:configChanges="orientation|screenSize">

以下是文档:http://developer.android.com/guide/topics/resources/runtime-changes.html

答案 1 :(得分:4)

我遇到了同样的问题。当你翻转屏幕时(至少在我的情况下)webView重新启动的原因是你在onCreate()运行时总是初始化webView,即使webView不是null。

首先在AndroidManifest.xml中添加以下内容:

<activity android:configChanges="orientation">

然后,尝试添加if子句:

...

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

...

答案 2 :(得分:1)

旋转设备时,Android restarts the application可帮助重新加载正确的配置文件。有几种方法可以解决这个问题。主要的两个是保存应用程序的状态,然后在配置更改后重新加载它,或告诉Android不要重置应用程序以进行某些方向更改。对于你的情况,我推荐后者(因为我没有使用WebView)。 Here's how.

将此添加到您不想重新启动的活动清单中。

  

&LT;活动android:name =“。MyActivity” android:configChanges =“orientation”&gt;

如果您想在配置更改上执行任何代码,请将其添加到您的Activity代码中。

@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);

    // Do something here
}

答案 3 :(得分:1)

这是2015年,许多人正在寻找仍然适用于Jellybean,KK和Lollipop手机的解决方案。 在很多挣扎之后,我发现了一种在更改方向后保持webview完好无损的方法。 我的策略基本上是将webview存储在另一个类的单独静态变量中。然后,如果发生旋转,我将webview从活动中分离出来,等待方向完成,然后将webview重新连接回活动。 例如......首先将它放在你的MANIFEST上(keyboardHidden和键盘是可选的):

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

在单独的应用程序类中,输入:

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

在ACTIVITY中:

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

最后,简单的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>

在我的解决方案中有几件事可以改进,但我已经花了很多时间,例如:验证Activity是否第一次启动而不是使用SharedPreferences存储的更短方法。 这种方法可以保留webview完整(afaik),其文本框,标签,UI,javascript变量以及未被网址反映的导航状态。