androidwebviewandroid-webviewactionbarsherlockscreen-rotation

WebView with SherlockActionBar reloads on rotation


I know there are a lot of similar questions and believe me, I tried a lot, but nothing worked out for me. I have a Android App which uses a Webview. You can find my App in the Play Store:

https://play.google.com/store/apps/details?id=at.rk.rps&feature=search_result#?t=W251bGwsMSwxLDEsImF0LnJrLnJwcyJd

After a few month in the Play Store I decided to make an update and to use the Android Design Guidelines for my new Design, so a Actionbar was necessary. I went with ActionbarSherlock and everything is fine, except the Webview is now reloading every time I rotate the phone. In my last version I handled this problem with this answer and it worked:

My Webview Reloads When I Change From Portrait To Landscape

But now it won't work again. I have tried that solution too: (I also left a comment at the end of the site)

http://www.devahead.com/blog/2012/01/preserving-the-state-of-an-android-webview-on-screen-orientation-change/

With the same disappointing result. I'm not even sure if ActionbarSherlock is the problem, because I've changed a lot, but it is impossible to recreate the old state!

This is what the App looks like (This is only in the new version implemented, you can't find it in the version which is publish on the Play Store):

loading screen

PayPal site

Here's a part of my code, first the manifest, then the layout and afterwards the java code:

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="at.rk.rps"
    android:versionCode="8"
    android:versionName="0.4" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="15" />

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.CALL_PHONE" />

    <application
        android:icon="@drawable/rps"
        android:label="@string/app_name"
        android:theme="@style/Theme.Sherlock.Light.DarkActionBar" >
        <activity
            android:name=".RPSActivity"
            android:configChanges="orientation"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name=".SettingsActivity"
            android:label="@string/app_name"
            android:windowSoftInputMode="stateHidden" >
        </activity>
        <activity
            android:name=".DonateActivity"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name=".PayPalActivity"
            android:configChanges="orientation"
            android:label="@string/app_name" >
        </activity>
        <activity
            android:name=".LoadingScreen"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <TextView
        android:id="@+id/paypal_loadingtext"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="90dp"
        android:gravity="center"
        android:text="@string/paypal_loadingtext"
        android:textAppearance="?android:attr/textAppearanceLarge"
        android:textColor="@color/rk_red" />

    <ProgressBar
        android:id="@+id/paypal_progressbar"
        style="?android:attr/progressBarStyleHorizontal"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_below="@+id/paypal_loadingtext"
        android:layout_marginLeft="40dp"
        android:layout_marginRight="40dp"
        android:layout_marginTop="10dp" />

         <WebView
        android:id="@+id/paypal_webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentTop="true"
        android:visibility="gone" />

</RelativeLayout>

Java code:

package at.rk.rps;

import org.apache.http.util.EncodingUtils;

import android.content.res.Configuration;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.actionbarsherlock.app.ActionBar;
import com.actionbarsherlock.app.SherlockActivity;
import com.actionbarsherlock.view.Menu;
import com.actionbarsherlock.view.MenuInflater;
import com.actionbarsherlock.view.MenuItem;

public class PayPalActivity extends SherlockActivity {

private ActionBar actionbar;
    private WebView webview;
    private TextView loadingtxt;
    private ProgressBar progressbar;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if(getSharedPreferences(RPSActivity.PREFS_NAME, 0).getBoolean(RPSActivity.FULLSCREEN, true)) this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);

        setContentView(R.layout.paypal);

        initUI();
    }

    private void  initUI() {

        actionbar = getSupportActionBar();
        actionbar.setTitle(R.string.paypal_actionbar_headline);
        actionbar.setHomeButtonEnabled(true);
        this.actionbar.setDisplayHomeAsUpEnabled(true);

        loadingtxt = (TextView) findViewById(R.id.paypal_loadingtext);
        progressbar = (ProgressBar) findViewById(R.id.paypal_progressbar);

        webview = (WebView) findViewById(R.id.paypal_webview);

        webview.requestFocus(View.FOCUS_DOWN); // Enables the keyboard in landscape mode
        webview.setOnTouchListener(new View.OnTouchListener() {             
            @Override
            public boolean onTouch(View v, MotionEvent event) {

                switch (event.getAction()) { 
                case MotionEvent.ACTION_DOWN: 
                case MotionEvent.ACTION_UP:
                    if (!v.hasFocus()) { 
                        v.requestFocus(); 
                    } 
                    break; 
                }

                return false; 
            }
        });

        webview.getSettings().setJavaScriptEnabled(true); // Enables JavaScript
        webview.getSettings().setBuiltInZoomControls(true); // Enables zoom

        webview.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY); // Displays scrollbars outside the view
        webview.setScrollbarFadingEnabled(false);       

        webview.getSettings().setLoadWithOverviewMode(true);
        webview.getSettings().setUseWideViewPort(true);

        webview.setWebChromeClient(new WebChromeClient() {
            public void onProgressChanged(WebView view, int progress) {

                loadingtxt.setVisibility(TextView.VISIBLE);
                progressbar.setVisibility(ProgressBar.VISIBLE);
                webview.setVisibility(WebView.GONE);

                progressbar.setProgress(progress);
                if(progress == 100) {
                    loadingtxt.setVisibility(LinearLayout.GONE);
                    progressbar.setVisibility(LinearLayout.GONE);
                    webview.setVisibility(WebView.VISIBLE);
                }
            }
        });

        webview.setWebViewClient(new WebViewClient());

        byte[] post = EncodingUtils.getBytes("cmd=_s-xclick&hosted_button_id=VRM63MEY4J936", "BASE64");
        webview.postUrl("https://www.paypal.com/cgi-bin/webscr", post);         

    }


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


    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(event.getAction() == KeyEvent.ACTION_DOWN){
            switch(keyCode)
            {
            case KeyEvent.KEYCODE_BACK:
                if(webview.canGoBack() == true){
                    webview.goBack();
                } else {
                    finish();
                }
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater i = getSupportMenuInflater();
        i.inflate(R.menu.paypal_menu, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle item selection
        switch (item.getItemId()) {
        case android.R.id.home:
            finish();
            return(true);

        case R.id.paypal_actionbar_reload:
            webview.reload();
            return(true);
        default:
            return super.onOptionsItemSelected(item);
        }
    }
}

Solution

  • I found the answer here:

    https://stackoverflow.com/a/9550231/1254514 "Beginning with Android 3.2 (API level 13), the "screen size" also changes when the device switches between portrait and landscape orientation."

    So I had to do the following:

    Add in your Android manifest to the activity you like:

    android:configChanges="keyboardHidden|orientation|screenSize"
    

    Then override the function in your activity:

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