Android ListView in Activity getting Refreshed on Changing Orientation - android

I have Activity with ListView inside it and in the onCreate method of the Activity I have code for populating the Data of the ListView this Data is a server based and so populating includes calling Network URLs. I have the ArrayAdapter of the ListView in the Same Activity Class.
Now the Issue I'am facing is that, in Rest all scenarios my Activity is behaving in a proper way but when the Orientation [ Portrait to Landscaped or other way round] is taking place the Data is Getting lost and Newer Data calls are Required to Populate the Same Old Data now this is something that is not intended out the code how should I deal with it.

Android will stop and restart your activity unless you've told it you will handle orientation changes yourself. It does this so that you can specify different resources (such as layouts) that are orientation-specific (among other reasons).
You need to add android:configChanges="orientation" to your activity delcaration in your AndroidManifest.xml, and you need to override onConfigurationChanged(). I don't believe you need to do anything special inside onConfigurationChanged(), simply implementing it should do the trick.

For those targeting API 13 or higher, "screenSize" should also be used. If that is your case, add
android:configChanges="orientation|screenSize"
to your Android manifest.
More information here.

AFAIK the whole Activity gets recreated on an orientation change!
The same is true if you switch to anoter app and return back later.
I would suggest to store the data is the SharedPreferences or serialize them into XML and store them.
Another possibility could be to register your own service that stores the data in memory and the activity poluplates the data from the service.

Why not saving any data into a parceable and if the bundle you get in onCreate contains a saved state of data re-set the list adapter? Here is a nice code sample on this: http://blog.cluepusher.dk/2009/10/28/writing-parcelable-classes-for-android/

android:configChanges="orientation|screenSize"
this code will work only if we don't have another layout for landscape mode!

Related

Why can't fragment save EditText state by default on orientation change?

I have a fragment, which contains many EditTexts.
And when I rotate the device the EditText goes blank. The fragment is not saving its state/value. But at the same time if I use that fragment layout for activity it stores the EditText's state.
And yes I've given the IDs to each EditText, even to each view if that matters.
I know I can use saveInstanceState to save those values but is there any other way to do it? Cause there are almost 20 EdiText in that fragment, so should I use saveInstanceState, will it be okay to save these many variables/values in saveInstanceState?
Update:
I was recreating the fragment in activity on orientation change, so that was the reason, EditText was unable to save its state.
Such a silly mistake!
So now I just used saveInstanceState like following:
if (savedInstanceState == null) {
initialiseNewTaskFragment();
}
And that's it. EditText is saving its state now.
Thank you JorgeGil for saving my time!
Well this is a fairly loaded question lol.
So let's start with a few points.
First, you can of course handle your own lifecycle change if you choose to NOT allow Android to reset your lifecycle on device rotate.
android:configChanges="orientation"
Use that flag in your manifest if you want to retain everything and handle your own rotation changes. However, if you have a layout-land folder with different XML files, you will not want to do this.
Yes of course you can do fragment.retainInstance when nested in Activities to get it to retain values. However, retaining populated Elements with values is not something you can just natively expect it to do as the UI elements were completely redrawn, so something has to tell it to redraw it again.
So if you are going old school and you are actually still doing findViewById and myText.setText('some Stuff'). Then you may find some time savings in using a library like icepick.
https://github.com/frankiesardo/icepick
However, the BEST option by a mile is to modernize your coding practice to use DataBinding. This allows you to not care about the UI interactions anymore as the values are bound to your Fragment or Activity or Model values by default and can be done with 2-way binding. This ensures databinding always populates with the value that was last updated.
Imagine you have an object of
public class Student implements BaseObservable{
String firstName;
}
Then in your xml you have
editText
android:text="#={student.firstName}"
Obviously there is a little more, like you need to set your student object in the onCreate to ensure it is in the XML for using. But when the user modifies the student firstname it is retained in the model, and redrawn automatically into the Edit Text.
This is your best solution, but depends on how invested you are in the future binding techniques of Android development or if you just prefer to go status quo to get across a finish line.
Hope that helps.
Add this in your Activity tag on your AndroidManifest.xml to avoid the recreation of the Activity and you won't lose the data.
android:configChanges="orientation|screenSize"

How to handle Screen rotation of activity which have more data?

I have one activity which has more than 20 fields, most of these fields will prompt user to set data.
Now the problem with the Configuration changes. If user set all the fields & he/she changed screen orientation, then all the fields will be reset because the activity will restart.
If I have only few fields means, then I would have gone with onSaveInstanceState() & onRestoreInstanceState().
But how to handle these many fields? Whether I have to go by storing all the fields? or Is there any better approach?
Try this way
<activity
android:name=".ActivityName"
android:configChanges="orientation|screenSize|keyboardHidden"/>
While you can prevent the activity from rotating to avoid the problem, this should only be done in special circumstances. Also, there are other situations where configuration changes can take place and cause problems. For a full discussion, see this: Why not use always android:configChanges="keyboardHidden|orientation"?
So my suggestion is that instead you create a holder class that implements Parcelable. Then on onSaveInstanceState(Bundle outState) simply call outState.putParcelable(key, yourParcelableObject). You would still need to update the corresponding fields on and this class but at least you would avoid having several keys and calling individual put to the bundle.
add android:configChanges="keyboardHidden|orientation|screenSize" to activity tag in manifest file but that is not best way please read Why not use always android:configChanges="keyboardHidden|orientation"? and http://developer.android.com/guide/topics/manifest/activity-element.html#config and http://developer.android.com/guide/topics/resources/runtime-changes.html for selecting best way for yourself here is a good example for using from parcle .

Restart activity as e.g. orientation change does

I want my app to support different layouts for right-handed and left-handed users. So after changing the respective preference I want to restart the activity in the same way as it restarts when e.g. orientation changes.
What I tried so far:
1.
Intent intent = getIntent();
finish();
startActivity(intent);
This does not store and load the saved instance state
2.
View cv = findViewById(android.R.id.content);
SparseArray<Parcelable> state = new SparseArray<Parcelable>();
cv.saveHierarchyState(state);
setContentView(desiredCv);
cv = findViewById(android.R.id.content);
cv.restoreHierarchyState(state);
Even then many things aren't as they should be.
I think that in the end I could figure out how to change layout properly without restarting but it would be much easier to do it in the same way as for system-defined configuration changes.
You could use Fragments and do it programmatically. Following the same way you could also rearrange dinamically your elements in the UI but I think it would be complicated to maintain.
OnSaveInstanceState() is not called on an Activity being finish-ed. And I'm not aware of a way to let Android handle this for you.
The solution may be to create 2 different layout files. Then you programmatically select the right one in the onCreate() method based on the preference value that has been updated.
If your two layouts use the same ids for those views that you need to restore, then you can implement two methods that save these states in a Bundle and retrieve these states from the Bundle. When you want to change layout, start a new activity with the proper intent (telling the activity which layout to load); in the bundle associated with this intent save what you need and retrieve it in onCreate() to update the views. You don't need to duplicate the code in the case you use layout dx or sx; you can use the same code since the two layouts use the same ids.
In this way you still have your one activity and can reuse your code. And the same code you use to restore the state between layout changes can still be used with onSaveInstanceState() and onRestoreInstanceState(), since, again, the ids are the same.
To make it short, use bundles.
If you are using API level 11 or higher (Android 3.0 or later), you can call recreate() in your activity. This will destroy the current instance and create a new one and should do the same thing as what happens during a configuration change (ie onSaveInstanceState() will be called, etc.).

How NOT to re-create activity after orintation in android?

I have activity the contains a ListView, and this listview is filled with data from a web service in onCreate() function ( using AsyncTask). When the screen orientation changes the activity is re-created, I don't want that. how to keep saved after changing the orientation
You need to add this in the Activity in AndroidManifest.xml. Just adding "orientation" will not work on all devices.
android:configChanges="orientation|screenSize"
Set android:configChanges="orientation" in your AndroidManifest.xml for the activity.
Although the other answers suggest using android:configChanges, I would say this is really only a last resort option because it means resources for different orientations will not get loaded automatically.
Instead you should use the onSaveInstanceState or onRetainNonConfigurationInstance functions of your activity. (If you use fragments, you should use setRetainInstance instead of the latter option.)
Another option would be to use a ContentProvider to store the data you download using the AsyncTask into a database so it wouldn't need to be re-downloaded anyway.
You should read this for more information.

includeed layouts - update in multiple activities

I have an app with multiple activities and multiple layouts. However, one piece of layout is included on several activities. I also have a thread which updates this layout. However, when i switch activity it doesn't work. Since the layout is included the elements have the same ID's, shouldn't it just work? Or do I really need to fetch an object for each element in the layout and feed it into my thread in order to make it update the elements in a new activity?
You should run the update code for each Activity/View, although the XML included is the same, each is a different instance.
My suggestion is on Restart verify is there is any modification to do in each activity, a simple way is to each Activity extend a BaseActivity that has this code.
I include a layout for adverts in my app, but on each activity that uses it, the adverts need to be reloaded.
If I call an activity from one that is using the same included layout when I go back to the previous activity it's still there.
I guess this is what you are seeing....
So you can also save that data inside sharedPreferences (if it is little data and primitive objets or parceable objects).
Also you can extend the Application class and store the data there and update every activity inside the onResume() method. that i believe is the best way to handle this. and this is quite simple to do.
Ask google about extending the application class and he will provide tons of results on how to do it. its an easy way to pass data between activities and/or keep a reference to a single object which you will use throughout the app. Just be carefull to clear it when you wont need it anymore because it will stay in existance untill the application is finished() (which comes with the application extension living thru the whole application lifetime).

Categories

Resources