I've got my app working for the most part, but I've got buttons and text views with text that change based on some state variables. When I change the device's orientation it destroys and recreates the activity in the new orientation. I've tried adding
android:configChanges="orientation"
to the manifest file. I've also tried overriding the onConfigurationChanges method to "do nothing" but the text still reverts to default.
I know I can lock the user in to one orientation, but I would rather have the app usable in either orientation.
Alternatively, is there a way to determine which orientation the user opened the app in and lock them in that orientation until they restart the app?
Edit:
Thank you Kabir,
android:configChanges="orientation|screenSize"
works perfectly
For API 12 and below:
android:configChanges="orientation"
if you are targeting API 13 or above
android:configChanges="orientation|screenSize"
Actually orientation changing works by destroying and recreating an activity. Some views are able to save theirs states, others no. TextView doesn't save its state (in this case text) as it tends to show static text. If you want to save TextView's state during the configuration changes, you can do as following:
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
/*
1st argument is key, 2nd is value to save
*/
outState.putString("savedText", myTextView.getText().toString());
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
/*
The argument is key to get saved string
*/
myTextView.setText(savedInstanceState.getString("savedText"));
}
These onSaveInstanceState() and onRestoreInstanceState() are Activiy's methods.
Related
I've got an Android application which maintains state regarding distance traveled, time elapsed, etc. This state I can conveniently store in an object and store a reference to that object in the Bundle when Android calls onDestroy() when the user changes the screen orientation, then restore the state in onCreate(Bundle savedBundle). However, I also have some state in the Buttons and EditText objects on the screen that I want to persist through screen orientations. For example, in onStart(Bundle savedBundle) I call:
_timerButton.setBackgroundColor(Color.GREEN);
_pauseButton.setBackgroundColor(Color.YELLOW);
_pauseButton.setEnabled(false);
Then throughout the operation of my app, the colors/enabled status of these buttons will be changed. Is there a more convenient way to persist the state of user interface items (EditText, Button objects, etc) without having to manually save/restore each attribute for each button? It feels really clumsy to have to manually manage this type of state in between screen orientations.
Thanks for any help.
Add android:configChanges in the Manifest file
<activity name= ".MainActivity"
android:configChanges="orientation|screenSize"/>
By default, this does not work because changing the orientation causes the onCreate method to be called again and redraws the view.
However, if this parameter is included, the framework will handle preserving the state of the screen or layout if the orientation is changed.
Refer following official documentation for more info:
Activity Lifecycle
Handling configuration changes
To save your variable or values you should use onSaveInstanceState(Bundle); and when orientation changes then should recover values should use onRestoreInstanceState() as well, but not very common. (onRestoreInstanceState() is called after onStart(), whereas onCreate() is called before onStart().
Use the put methods to store values in onSaveInstanceState()
protected void onSaveInstanceState(Bundle icicle) {
super.onSaveInstanceState(icicle);
icicle.putLong("param", value);
}
And restore the values in onCreate():
public void onCreate(Bundle icicle) {
if (icicle != null){
value = icicle.getLong("param");
}
}
I have an app that adds to a total variable when a button is clicked.
However if I turn my phone so the layout gets turned into the horizontal layout the values all get reset, and idea why this is and how to stop it?
Thanks!
When you move your device, your device's Orientation State changes from Portrait to Landscape of from Lanscape to Portrait.
In this Orientation change, your Activity's onCreate Method is called every time.
Therefore the values in your Activity are being reset.
There are 2 ways of solving this problem:
1) Let You Activity manage it for you.
2) Managing the changes yourself by saving and restoring states.
Using 1st way of solving this problem:
Just add this line in your Activity Node in your Manifest.xml file.
android:configChanges="orientation|keyboardHidden|screenSize"
For example:
<activity
android:name=".MyMainActivity"
android:configChanges="orientation|keyboardHidden|screenSize"
android:label="#string/app_name" >
Using the second Way:
You can override these two Methods:
public void onSaveInstanceState(Bundle bundle) {
super.onSaveInstanceState(bundle);
//Manage your Data Explicitly here.
}
public void onRestoreInstanceState(Bundle bundle) {
super.onRestoreInstanceState(bundle);
//Manage your Data Explicitly here.
}
EDITAccording to Android Dev Guide:
Using android:configChanges="orientation|keyboardHidden|screenSize" is not a good practice.
Quote from this page
Note: Using this attribute should be avoided and used only as a last resort. Please read Handling Runtime Changes for more information about how to properly handle a restart due to a configuration change.
I recommend you to follow the Android Dev Guide for Handling Run-time Changes and follow the good Practices.
you need to save the variable in OnSaveInstanceState and restore it in onRestoreInstnace state
For example;
#Override
public void onSaveInstanceState(Bundle bundle) {
bundle.putParcelableArrayList(PEOPLE, people);
super.onSaveInstanceState(bundle);
}
#Override
public void onRestoreInstanceState(Bundle bundle) {
super.onRestoreInstanceState(bundle);
people = bundle.getParcelableArrayList(PEOPLE);
}
This happens because the normal way Android handles an activity during any configuration change (including screen reorientations) is to destroy the activity and recreate it. As described in the guide topic Handling Runtime Changes, you can handle it a couple of ways. The "Android way" is to save your activity's state information by overriding onSaveInstanceState and onRestoreInstanceState methods. The details about how to use these methods can be found in the guide topic Recreating an Activity.
The other way to prevent this problem is to tell Android that your activity will handle configuration changes internally. You do this by adding android:configChanges="orientation" to the <activity> tag in the manifest for the activity and overriding the onConfigurationChanged method of the activity to actually handle the changes.
I am working on android apps. My app should work both in portrait and landscape mode. I adjusted all the layouts by keeping all layout files in layout-lan folder. But now my issue is with functionality i.e when the app is changed to landscape mode the values of my parameters are changing and due to this I am getting crashes. i.e i kept a counter value but it is displaying wrong count value when turned to port-lan. Also the functionality is changing due to this.
Please help me in this regard.
Each time you rotate the devide, onCreate method is being called again. You can save the values by overriding onSavedInstanceState and get them back in onRestoreInstanceState or in onCreate method. For example:
save the value:
public void onSaveInstanceState(Bundle outState) {
outState.putBoolean("booleanValue", true);
}
restore the value (you can call this in onCreate as well):
protected void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null && savedInstanceState.containsKey("booleanValue")) {
boolean myBoolean = savedInstanceState.getBoolean("booleanValue");
}
super.onRestoreInstanceState(savedInstanceState);
}
Your activity restarts every time the orientation changes.
You have to store your values in onSaveInstanceState and restore them in onRestoreInstanceState. You will find the details here: http://developer.android.com/guide/topics/resources/runtime-changes.html
those values change because the activity gets destroyed and re-built during rotation,
please check the developers guide on how to save your activity state.
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
I have seen the following links before posting this question
http://www.devx.com/wireless/Article/40792/1954
Saving Android Activity state using Save Instance State
http://www.gitshah.com/2011/03/how-to-handle-screen-orientation_28.html
How to save state during orientation change in Android if the state is made of my classes?
I am not getting how should i override the following function :
#Override
public Object onRetainNonConfigurationInstance() {
return someExpensiveObject;
}
In my application i have layout with one editext visible and other editext get visible when the data of first editext validates to true.I have set the visbility of all other editextes and textviews to false and make them visible after validating.
So in my activity if the screen orientation is changed then all the items having android:visibility="false" get invisible.
I have also came to know that when our activities screen orientation changes it calls onStop() followed by onDestroy() and then again starts a fresh activity by calling onCreate()
This is the cause .. But i am not getting how to resolve it ..
Here You can see the screenshots of my application :
in this image all fields are loaded
and in another image when the screen orientation is changed to landscape they are all gone
Any link to tutorial or piece of code will be highly appreciable.
And also my application crashes when a progress dialog is shown up and i try to change screen orientation.How to handle this ??
Thanks
Well if you have the same layout for both screens then there is no need to do so just add below line in your manifest in Activity node
android:configChanges="keyboardHidden|orientation"
for Android 3.2 (API level 13) and newer:
android:configChanges="keyboardHidden|orientation|screenSize"
because the "screen size" also changes when the device switches between portrait and landscape orientation.
From documentation here: http://developer.android.com/guide/topics/manifest/activity-element.html
There is another possibility using which you can keep the state as it is even on Orientation change using the onConfigurationChanged(Configuration newConfig).
Called by the system when the device configuration changes while your activity is running. Note that this will only be called if you have selected configurations you would like to handle with the configChanges attribute in your manifest. If any configuration change occurs that is not selected to be reported by that attribute, then instead of reporting it the system will stop and restart the activity (to have it launched with the new configuration).
At the time that this function has been called, your Resources object will have been updated to return resource values matching the new configuration.
There are 2 ways of doing this, the first one is in the AndroidManifest.xml file. You can add this to your activity's tag. This documentation will give you an in depth explanation, but put simply it uses these values and tells the activity not to restart when one of these values changes.
android:configChanges="keyboardHidden|orientation|screenSize|screenLayout"
And the second one is: overriding onSaveInstanceState and onRestoreInstanceState. This method requires some more effort, but arguably is better. onSaveInstanceState saves the values set (manually by the developer) from the activity before it's killed, and onRestoreInstanceState restores that information after onStart() Refer to the official documentation for a more in depth look. You don't have to implement onRestoreInstanceState, but that would involve sticking that code in onCreate().
In my sample code below, I am saving 2 int values, the current position of the spinner as well as a radio button.
#Override
public void onSaveInstanceState(#NonNull Bundle savedInstanceState) {
spinPosition = options.getSelectedItemPosition();
savedInstanceState.putInt(Constants.KEY, spinPosition);
savedInstanceState.putInt(Constants.KEY_RADIO, radioPosition);
super.onSaveInstanceState(savedInstanceState);
}
// And we restore those values with `getInt`, then we can pass those stored values into the spinner and radio button group, for example, to select the same values that we saved earlier.
#Override
public void onRestoreInstanceState(#NotNull Bundle savedInstanceState) {
spinPosition = savedInstanceState.getInt(Constants.KEY);
radioPosition = savedInstanceState.getInt(Constants.KEY_RADIO);
options.setSelection(spinPosition, true);
type.check(radioPosition);
super.onRestoreInstanceState(savedInstanceState);
}
friends,
i am facing an issue related to android phone screen orientation
If i change the orientation of the phone, then it loses the context, if i am in middle of filling a simple form. So, the phone is vertical, I am using soft keyboard, I make it horizontal, so that I can use the keyboard easily again or something else, and kaboom, everything I have entered so far is lost.
any one guide me what is the solution to keep data and state same after changing orientation?
any help would be appriciated.
That's because activity is actually re-created on orientation change. You have to save your state before the change and then restore it. Override onSaveInstanceState to save your data to bundle. The data is then accessible at onCreate (withing the bundle again).
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putSerializable("Key", "Some data"); //put some data
super.onSaveInstanceState(outState);
}