As usual in android, each time the screen is flipped to portrait/landscape mode an Activity runs through life-cycle from onSaveInstanceState to onDestroy and then is recreated.
In my Activity there's a ButtonText which can be changed by the user. It's reseted to the initial state, but I have to save the last state somehow. How can I achieve that, will I have to override onSaveInstanceState? Can someone show an example?
I had the same problem and expected that the default implementation would take care of restoring a button's text. Unfortunately it did not. Finally I found the attribute android:freezesText respectively the method setFreezesText(boolean). When set to true the button will restore its text automatically.
See the reference of Button's super class TextView: http://developer.android.com/reference/android/widget/TextView.html#attr_android:freezesText
Step #1: Call getText().toString() on the Button to get the caption.
Step #2: Call putString() on the Bundle passed to your implementation of onSaveInstanceState() to store the caption.
Step #3: Call getString() on the Bundle passed to your implementation of onRestoreInstanceState() (or in onCreate(), if the Bundle is not null, if you wish) to get your caption back, then call setText() on your Button to put the caption back in.
Here is a sample project that uses onSaveInstanceState() to save a Uri of a contact (which also affects whether or not a Button is enabled).
Related
I do have 2 activities A (contains a button that redirects to A and a text input) and B (contains a button the redirects to A) and I was trying to switch from one to another but also to keep the text value from A.
I was trying to save the text value in a Bundle using onSaveInstanceState(...) but it simply didn't work.
Here are the steps I do:
(on A) add some text
in A, implement onSaveInstanceState(...) and save the value of text in Bundle
(on B) click the button that points back to A
(on A) the stored value is gone (also the Bundle sent to onCreate(...) is null)
To my surprise when I'm in A and change the orientation the value is stored (and the Bundle sent to onCreate(...) is not null)
Did I miss something?
In short, no.
onSaveInstanceState is meant to save the instance state during things like:
Memory pressure
Screen rotation
Whenever the system decides to stop the activity and resume it later (e.g. it moves to the background, get's forgotten by the user, and later is being picked up again).
Further reading is available here.
You should store those values you want to keep in SharedPreferences, for example during your onPause call.
No you can not use onSaveInstanceState() while switching between activities.
onSaveInstanceState() Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(Bundle) or onRestoreInstanceState(Bundle) (the Bundle populated by this method will be passed to both).
This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(Bundle) or onRestoreInstanceState(Bundle).
You can get more idea on Android Developer pages:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html
http://developer.android.com/reference/android/app/Activity.html#onSaveInstanceState(android.os.Bundle)
I'm newbie in android and I'm working with fragments.
My problem:
I have two fragments, "A" and "B", my fragment "A" is a complex form, the user can add and remove products, set customer information, payment method and more. My fragment "B" just show the information that user set in the previous fragment.
But if user press back button, I'm losing all information that already set in the previous fragment.
How can i maintain this informations on fragment A?
Thanks.
you can save your data by using sharedpreferences
so that once you get back to the fragment you load your data from sharedpreferences
You should add android:id attribute to each View element of which state you want to save.
this explains in android documentation:
By default, the system uses the Bundle instance state to save information about each View object in your activity layout (such as the text value entered into an EditText object). So, if your activity instance is destroyed and recreated, the state of the layout is restored to its previous state with no code required by you. However, your activity might have more state information that you'd like to restore, such as member variables that track the user's progress in the activity.
Note: In order for the Android system to restore the state of the views in your activity, each view must have a unique ID, supplied by the android:id attribute.
To save additional data about the activity state, you must override the onSaveInstanceState() callback method. The system calls this method when the user is leaving your activity and passes it the Bundle object that will be saved in the event that your activity is destroyed unexpectedly. If the system must recreate the activity instance later, it passes the same Bundle object to both the onRestoreInstanceState() and onCreate() methods.
I have developed an application and it contains web view.
My issue
When my phone's orientation changes from portrait to landscape the whole application loads again and the web view reloads showing the first page of website.
So I am getting confused about the screen orientation or saving the data during that phase, so how do I fix it...
Yes, in Android the Activity is destroyed and recreated when your change the screen orientation. Thus you need to restore your applications state on recreation. On way is to use the callback method onSaveInstanceState() which you can use to save the state in a Bundle.
The Activities are explained here: http://developer.android.com/guide/components/activities.html and I suggest you take a look on that page for examples and more detailed instructions.
The default behaviour is to restart the activity when a configuration change happens (such as orientation change).
To override this you need to tell the system you'll handle orientation change yourself by adding this to your manifest file in your <activity> element:
android:configChanges="keyboardHidden|orientation|screenSize"
You may also want to override onConfigurationChanged which will be called when such a change happens.
See http://developer.android.com/guide/topics/manifest/activity-element.html#config
The Android Activity lifecycle clearly indicates this behaviour .
What happens
Whenever you start an Activty is gets created(after onStart() method) the
onCreate(Bundle onSavedInstance)
The variable onSavedInstance mentioned above initially recieves null as nothing is saved.
But during the orientation the whole layout hierarchy has to adjust according to the new mode from an existing mode(from portrait->landscape or vice-versa).This change may remove the previous data that you had in your activity.So to avoid such a problem(loosing data), there is a method
onConfigurationChange(Bundle saveSomething)
This method will be called for you to handle some configuration changes into this,
The default implementation will save you some data like some text in an editText.
Note This method as far the specs goes should be used to save some trivial data.
Example
Suppose you had applied a background colour to the activty layout and now you rotated it default implementation won't save it but onConfigurationChange if you want you can save it like this
saveSomething.putInt("color",1);
Inside onCreate
protected void onCreate(Bundle onSavedInstance){
if(onSavedInstance!=null){
int color=onSavedInstance.getInt("color");
if(color==1){
setBackgroundColor(Color.BLACK);
}
}
}
Add the following line inside the activity element of your manifest file you will be handling the changes in configuration
android:configChanges="keyboardHidden|orientation|screenSize"
Let's say
First.class
has a variable
String currentValue = "Red"
with a button that leads to Second.class (an activity). First.class(Activity) displays in a textview what the variable currentValue happens to be. (Currently, Red).
If we push the button, it takes us to Second.class, which has an EditText box to modify the variable in First.class. It also has a button to confirm the change. Finally, it has a TextView at the very bottom showing a preview of what First.class' value variable is.
When a user types in "Blue" in Second.class' EditText box and hits the button, how would we change the variable from First.class without using intents and going back to that activity? I want to stay within Second.activity and do the changes from there.
After hitting the confirm button, the preview TextView should update to match the newly modified variable. We should still be seeing Second.class, I remind you. If the user hits "Back" or "up" at this point, they should return to First.class and also see that the TextView in First.class has been changed.
How do I modify First.class' variables if Second.class is entirely separate from First.class and cannot access it? (First.class is the hierarchical parent of Second.class.
How do I modify First.class' variables if Second.class is entirely separate from First.class and cannot access it?
You can't or (more importantly) you should not try to do this.
The Android Activity is a "special case" class and should be generally considered as being self-contained. In other words any changes to data in the second Activity which need to be reflected in the first Activity must be either persisted using some form of global storage (SharedPreferences for example) or should be passed using the extras of an Intent or a Bundle.
With SharedPreferences simply have the first Activity save your currentValue before starting the second Activity and do the reverse in second Activity before returning to the first. The first Activity then simply needs to check the SharedPreferences in onResume() and update its TextView if necessary.
As codeMagic mentioned, however, simply using startActivityForResult(...) would allow passing currentValue from the first to the second Activity and, before the second exits, updating the Bundle with any changes will allow it to be passed back to the first Activity through onActivityResult(...).
I realized that there are lots of question on this topic already asked on SO.
But I don't even know the basic when it comes to saving the state of an activity.
(Refer Screenshot Below) When app launches,
1) ScrollView item 1,2,3,4 are visible
2) table containd data which is populated due to Gainer button.
As showed in below screenshots, While app is running in PORTRAIT mode, I
1)scrolled down to ScrollView item 4,5,6
2)pressed the Loser button so accordingly data in the table below the button changes.
3)I'll even change content of graph dynamically(which I had not done yet).
Now I switch to LANDSCAPE Mode so
1)ScrollView is showing ScrollView item 1,2,3,4
2)table is showing data which is populated due to pressing Gainer button.
3)graph is as it is as I've not changed it yet(which I will change later).
So what happens is when I change the orientation, my activity is getting re-launched. So if user is performing some task in one orientation and he changes the orientation, then whole progress will be lost.
I know I need to save the state of the activity and Restore it when orientation changes.
But I don't know from where to start and what to save.
ANY HELP WILL BE LIFE-SAVER !
Option #1: Override onSaveInstanceState() of your Activity and put whatever information you want in the supplied Bundle. Your new activity instance will receive that Bundle in onRestoreInstanceState() (or onCreate()). Here is a sample project demonstrating this.
Option #2: Override onRetainNonConfigurationInstance() of your Activity and return some object that represents your state. Your new activity instance can call getLastNonConfigurationInstance() to retrieve that object, so the new activity can apply that information. Be careful, though, not to have the old activity return something in the object that holds a reference back to the old activity (e.g., a widget, an instance of a regular inner class). Here is a sample project demonstrating this.
Option #3: Convert this activity to a fragment. Have the fragment call setRetainInstance(true); on itself during its initial setup. Add the fragment dynamically to some activity via a FragmentTransaction. Now, when the configuration changes, the fragment is retained, so all your widgets and state are retained. Here is an overly-complex sample application demonstrating this.
Those are the three recommended approaches nowadays.