Saving the list data on screen orientation in Android - android

I have one datepicker and one search button. On search button click, I have to pass the selected date to backend and display the fetched data in listview below search button.
In portrait mode I am able to display the data listview after clicking on search button. But when I rotate the emulator all the data getting lost.
How can I preserve the searched data to display in listview in landscape mode.
Please help me. Share some example code if possible.

android:configChanges="orientation|screenSize"
add this line inside your activity in manifest file.
then data will not lose during orientation change

Look into using onSaveInstanceState and onRestoreInstanceState. Or you could save the data you need into SharedPreferences, however, personally I'd use the InstanceState methods

You could lock the activity in one orientation by adding android:screenOrientation="portrait" (or "landscape") to in your manifest.
you could distinguish the cases of your activity being created for the first time and being restored from savedInstanceState. This is done by overriding onSaveInstanceState and checking the parameter of onCreate.
android:configChanges="screenOrientation" in the tag. This way the activity will not be recreated, but will receive a callback instead (which you can ignore as it's not useful for you).

Related

Stop reload application when orientation changes

I need my app to not reload when the orientation changes. I have a regular portrait and a seperate landscape layout that both have the same stuff on the screen. But when I check a checkbox and change layout, it's no longer checked. Or when a checkbox has the number 5 in it and then change layout it goes back to it's default number 1. How can I make it stop reloading?
You need to use a way to persist data between the two screens.
Either use savedInstanceState or ViewModel.
The checked state of a CheckBox and text in an EditText will be automatically preserved if you make sure they have the same id in both layouts. However, it only automatically preserves the things that can be changed through the UI, so if you programmatically changed the text of a CheckBox, that is not automatically preserved. Typically, that sort of thing is handled with a ViewModel and LiveData/Flow.
This behavior is controlled by the saveEnabled property of a view, which is true by default.
add this following permission for your activity in Manifest file android:configChanges="orientation|screenSize
Something like this
<activity
android:name=".YourActvity"
android:configChanges="orientation|screenSize">
First tip from Philipp Lackner explains how to use the savedStateHandle
https://www.youtube.com/watch?v=0d5ax97Mb30
The state when you change orientation, for example, gets restored, so you need to handle via viewmodel the state persistence.

Saving/loading an Android layout with previously programmatically added buttons

I have a very simple question about loading layout in main activity. I have a simple layout defined in activity_main.xml which is loaded in MainActivity's OnCreate() using
setContentView(R.layout.activity_main).
Then on a button click, I add another view item (button) which shows up correctly.
But when the app is closed and opened again, I need to retain what was added last time when the app closed. How do I do that?
I searched some questions here, but most of them talk about saving values using SharedPreferences or saving state, but it is not clear if the layout can be saved as well.
Thanks in advance.
I think the best solution is saving latest state values by using SharedPreferences, because it is a good way to save any simple data for long term.
Saving state via using saveInstanceState is a short term solution and if you close your app completely, saved instance will be gone forever.
Possible solution:
First, you cannot save a layout as you think, but you can get the layout's parameters and other features as variables, then you can save these by using SharedPreferences.
Secondly, you should check if there is any saved layout states when you start the activity. If any, you can use the pre-saved parameters for adding your layout dynamically/programmatically.

Stopping onCreate being executed on screen rotation in Android

I have an activity with 4 elements. A spinner containing a list of dates, a spinner containing a list of hours, a button and a list view. The spinner's selected items are used to form a web service URL which is called when the button is clicked and the response is shown in the list view.
The issue is if the user views the app in portrait mode, chooses a date, chooses an hour and clicks the button, the response of the web service call is shown in the list view however, if the device is rotated to landscape then the data in the list view is gone (because in order to get it there a button click is needed).
I understand that onCreate is called when the screen is rotated. I do not want to force the orientation so is there any way I can stop the list view being cleared? Note that the selected values in my spinners remain the same after rotation, it is just the response in the list view that is lost.
Simplest way to prevent activity recreation put this in you AndroidManifest
<activity android:name=".YourActivityName"
android:configChanges="orientation|keyboardHidden|screenSize">
Read this for more info - Supporting Multiple Screens
You can force activity screen orientation in AndroidManifest.xml by setting screenOrientation property:
<activity android:name=".FooActivity"
android:screenOrientation="portrait"/>
This is a half-solution. If you want to handle screen rotation, you should save and restore activity state. This is the major, royal PITA in any Android application I've seen.
The problem is, that your application logic is mixed with view code, which can be destroyed at any moment. Perfect combination, Google! It's like running a function that can disappear during execution. :)
To counter this sorry design decision you may want to move your application logic to service, which will not be destroyed when screen rotates. This 2-layer design is closer to universally accepted MVC pattern, as you separate your logic from your view. Service stays, activity attaches and detaches from service on demand, making screen rotation handling a breeze.
If you're dealing with webservices, do not try to invent your own solution for this. There is couple of nice libraries to handle this nicely, such as RoboSpice and you'll probably never come with any quick solution that is as good as those libs. Give it a try.
Also, watch this Google I/O video about developing Android REST client applications: https://www.youtube.com/watch?v=xHXn3Kg2IQE
Have your button set a static class variable, or shared preference. Then, call a method that reads that value, and does what you want. THEN, put a call to that same method, in onResume(), possibly based on a condition... I think that's what's worked for me. When you come back from configuration change or kill, onResume() should re-do whatever you had last done.

When to use saveInstanceState() method?

I know saveInstanceState() is used to store activity variables, text in EditText, etc.
But I have a doubt that should I save state of view?
Let me give you a scenario. My view has 3 buttons. On clicking one of them, a WebView is displayed to user (in same activity). Now if app gets killed, should I save state that user was displayed WebView when app got killed and when activity gets recreated display WebView instead of buttons?
Other scenario is, I have 3 tabs in view. Selecting each tab shows different view. As explained in above case again should I save that user has last selected this tab?
It will be best if you can explain the cases where I should and should not save activity state.
The operating system knows when it should re-create your app's previous state (the screen orientation changed or your app was killed in the background by the OS) and when to create a new instance (the user left your app with the back button). The onRestoreInstanceState() method is only called when there's a state to restore (when the system is restoring a previous state, as opposed to creating a new instance of the activity).
The short answer, then, is that if you override onSaveInstanceState() and onRestoreInstanceState(), the system will call them when appropriate, and you don't have to worry about deciding when you "should" save state.
When overriding onSaveInstanceState(), yes, you should save everything about your activity's state. This is the method being used during screen orientation change. Think about it - if you rotate your phone, do you expect the current app to change tabs, or the screen that just opened to disappear?
For more information, see the Android documentation on recreating an activity.
I have not done very much research on savedIntanceState on app gets killed. But yes you may save maybe a integer variable (referring to which button is clicked) in state, so that when activity is recreated, you know which webview used to be shown (or none). Same goes to your second situation.
Some extra use case of saved instance state:
One of the most used scenario is during user switches orientation, say you have a couple of edit texts on screen, their holding texts would be gone if user change his device orientation. Saved instance state helps you to recover the entered texts.
Another situation is you will most likely have a few class variable in your activity, probably used to save what user has done, or some temporary list object in a list activity. Saving those variables also prevents you from needing to recover the data on orientation change.

Override Orientation Change But NOT Restart The Activity AND Pass State Data

I want to be able to change the layout when a device is re-orientated to landscape or portrait. For speed and resource purposes (plus other issues applicable to my app) I do NOT want my app to be destroyed and restarted. I have several objects which I wish to retain between orientation changes as there is no benefit from destroying and re-creating them! I simply just want to change the position of some buttons and TextViews so that they suit the current orientation. Easy right?
Well no it isn't. To achieve the above I included in the app Manifest the configChange option for orientation change. Then I've implemented the onConfigurationChanged() where I determine and apply the appropriate layout. Simple yes?
But now take the textview I have in my layout. How on earth, using this particular method of responding to orientation changes, do I put the same text in the previous textview to the new textview? No instance data is passed to onConfigurationChanged() method. Also for some of the buttons, they could be disabled or enabled... I need to know this after orienatation change.
If I let Android destroy and restart my activity it's first going to create unnecessary work. All I want is to just move a few buttons and textviews.. NOT restart the whole app. That's just ludicrous!
Can anyone help me achieve what need?
An easy way to maintain configuration-independent data is to make use of onRetainNonConfigurationInstance() and its companion method getLastNonConfigurationInstance(). Just return an object that contains all the data that you want to reuse when your activity is recreated.
In Honeycomb, or if you are using the Android compatibility package, you can just call Fragment.setRetainInstance(true) instead. See the docs.

Categories

Resources