0

I am aware this has been asked a huge number of times, but I just cannot so get this to work. I am using two constraint layouts, and the switching between them works fine. However, the values on screen are reset, as per a million other questions here. This behaviour seems wildly inconsistent, as I've used it before in another project (where it worked for one activity but not another one), but I cannot get it to work now.

I am running my code on the android emulator, android 7.1.1, API 25

I have put

android:configChanges="keyboardHidden|orientation|screenSize"

in

<activity>

in androidManifest.xml

and

public void onConfigurationChanged(Configuration newConfig) {
          super.onConfigurationChanged(newConfig);
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
            setContentView(R.layout.activity_my_activity_land);
        } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
            setContentView(R.layout.activity_my_activity);
        }
    }

in my relevant activity.

The orientation changes and the layouts are loaded correctly, but the values are still reset.

I have looked at these answers and lots of similar ones:

Android activity restarted at orientation change even with configChanges set

layout-land is not working?

Save data and change orientation

Any way I can do this without doing like this suggests? (recreating the activity):

https://developer.android.com/training/basics/activity-lifecycle/recreating.html

Any help is greatly appreciated!

Community
  • 1
  • 1
Kyrre
  • 670
  • 1
  • 5
  • 19

2 Answers2

0

I think you should store the object you want to keep in a global variable and put it back every orientation change, because I guess your fragment is not getting destroyed but your views do are getting reconstructed.

if (mObject == null){ mObject = new mObject(); }

and then you just put it back in your Layout or wherever you need it like

myFrameLayout.addView(mObject);

I have an example of how I managed to use it with a WebView here:

private void initUI() {

    webViewPlaceholder = ((FrameLayout) view.findViewById(R.id.webViewPlaceholder));
    // Initialize the WebView if necessary
    if (myWebView == null) {
        webViewProgressBar = (ProgressBar) view.findViewById(R.id.webview_progressBar);
        webViewProgressBar.setScaleY(3f);
        // Create the webview
        myWebView = new WebView(activity);
        WebSettings webSettings = myWebView.getSettings();
        webSettings.setJavaScriptEnabled(true);
        webSettings.setPluginState(WebSettings.PluginState.ON);
        webSettings.setAllowFileAccess(true);
        webSettings.setGeolocationEnabled(true);
        webSettings.setLoadsImagesAutomatically(true);
        webSettings.setLoadWithOverviewMode(true);
        webSettings.setUseWideViewPort(true);
        webSettings.setSupportZoom(true);
        webSettings.setBuiltInZoomControls(true);
        myWebView.setLayoutParams(new ViewGroup.LayoutParams(RelativeLayout.LayoutParams.FILL_PARENT, RelativeLayout.LayoutParams.FILL_PARENT));
        myWebView.setScrollBarStyle(WebView.SCROLLBARS_OUTSIDE_OVERLAY);
        myWebView.setScrollbarFadingEnabled(true);
        mWebAppInterface = new WebAppInterface(activity, this,  myWebView);
        myWebView.addJavascriptInterface((mWebAppInterface), "Android");

        myWebView.setWebViewClient(new MyWebViewClient());
        myWebView.setWebChromeClient(new GeoWebChromeClient());

        // Load a page
        myWebView.loadUrl(getResources().getText(R.string.url).toString());

    }
    // Attach the WebView to its placeholder
    webViewPlaceholder.removeAllViews();
    webViewPlaceholder.addView(myWebView);
}

and I just call initUI() in my onCreateView() callback

Pedro Antonio
  • 250
  • 1
  • 5
  • 17
  • Thank you very much. This is a bit heavy, though. I do not wish to recreate the activity in that sense. Seeing as the different layouts do load for different orientations, there has to be a way for a View with the same id in both to keep its value onConfigurationChanged. I have used it myself and have seen many correct answers using the above technique. I feel I must be missing something obvious about my specific use.. – Kyrre Dec 13 '16 at 21:51
  • I mean you could manage the view programatically and store it, just put a placeholder in both layouts. And when the Layout gets recreated all your layout load according to the orientation. So then you just put the view you stored previously in the placeholder. you are not storing the whole activity, just the view you dont want to keep. – Pedro Antonio Dec 13 '16 at 22:10
0

When you orientate your device, it recall onCreate() method of your activity and redraw your views. For this you can create a helper fragment and put your operations in that fragment. Put this line setRetainInstance(true); in onCreate() method of your fragment. Then, do your operations in AsyncTask class. Create two methods, like setData(List<T> list) and getData(). Then, create an interface, withPostExecute callback and put this callback in onPostExecute() method. Then you can handle this operations via implementing that interface which you created in your fragment. I have simple repository in github which can help you. Eyjoy! This article also can help you: Enjoy!

JavadKhan
  • 625
  • 6
  • 18