I am new to android. I am doing a sample project on calculation of numbers. And i am using both portrait and landscape layouts. Whenever I change the orientation, my activity is newly created and all the previously entered values get lost. So, I tried to stop activity recreation by android:configChanges="keyboardHidden|screenSize|orientation" and by setting orientation only to android:screenOrientation="portrait". But this makes my portrait layout to fit in landscape mode. But I don't want this. I need to load my separate portrait and landscape layouts on orientation change with same set of values which was previously created(i.e load different layouts without activity recreation).
And also I tried of using overridden methods like onConfigurationchanged, onSaveInstanceState, onRestoreInstanceState. But still values are lost in using onConfigurationchanged method , and activity is recreated in using onSaveInstanceState and onRestoreInstanceState methods (Still the previous values are retrieved here).
Any solution for this?
Thanks in advance.
To resolve this you need to save and retrieve data in/from saved instance state
#Override
protected void onSaveInstanceState(Bundle outState) {
// TODO Auto-generated method stub
super.onSaveInstanceState(outState);
// Example to save the value of editText01 in SavedInstanceState
String stateToSave = editText01.getText().toString();
outState.putString("saved_state", stateToSave);
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onRestoreInstanceState(savedInstanceState);
//To Retrieve data from "saved_state"
String stateSaved = savedInstanceState.getString("saved_state");
edittextEditState.setText(stateSaved);
}
}
}
you should look at the onPause{} and onResume{} methods of the activity. because whenever your orientation is changed the activity is paused and then recreated again so you data is lost. and to understand better you should take a look at the activity life cycle
http://developer.android.com/reference/android/app/Activity.html... :)
delete android:screenOrientation="portrait" and give this code, android:configChanges="keyboardHidden|screenSize"
Related
I am new to java and android studio and after reading documentation I am still a little confused with the activity lifecycle and how to use it effectively.
I am building an application which has several activities. There is key data loaded in when the app is first opened in the main activity. However when I move to another activity and then back to the main, the onCreate is invoked again which I do not want. I am aware there is a way to save the instance of your onCreate but I am still unsure of how to do this. Here is what I have done:
#Override
protected void onSaveInstanceState(#NonNull Bundle outState) {
super.onSaveInstanceState(outState);
if (outState != null) {
// Restore value of members from saved state
outState.putString("step_count", String.valueOf(stepCount));
outState.putString("cal_count", String.valueOf(calCount));
outState.putString("dis_count", String.valueOf(disCount));
android.util.Log.d(TAG, "onSaveInstanceState");
} else {
// Probably initialize members with default values for a new instance
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
savedInstanceState.getString("step_count", String.valueOf(stepCount));
savedInstanceState.getString("cal_count", String.valueOf(calCount));
savedInstanceState.getString("dis_count", String.valueOf(disCount));
stepCount.setText(String.valueOf(stepCount));
calCount.setText(String.valueOf(calCount));
disCount.setText(String.valueOf(disCount));
android.util.Log.d(TAG, "onRestoreInstanceState");
}
Would appreciate any sort of support and guidance. Thank you.
Again - not a simple question.
First of all: Yes, you can save data "from last session" by overriding: onSaveInstanceState() and restore it overriding onRestoreInstanceState(savedInstanceState: Bundle?). Look here: https://developer.android.com/guide/components/activities/activity-lifecycle#saras
Second of all: According to your description it seems that you need SharedPreferences more than this. If you need a key to anything and it should be used from opening of the app until it is killed or user is logged out, SharedPreferences are the most common solution.
onSaveinstanceState() was created to make possibility to remember what was on the screen "in the last session" without "calculating" it again. For example EditText.text or ImageView.url or similar.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// get orientation
LinearLayout layout = isLandscape()
? (LinearLayout) this.findViewById(R.id.main_layout_l)
: (LinearLayout) this.findViewById(R.id.main_layout_p);
Log.i("info", "layout is " + layout.getId());
start();
run();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
Log.e("On Config Change",
(newConfig.orientation==Configuration.ORIENTATION_LANDSCAPE)
? "LANDSCAPE" : "PORTRAIT");
// added -- this fixes the background not showing
setContentView(R.layout.activity_main);
}
I have two layouts (two files, layout/activity_main.xml, layout-land/activity.xml) for both orientations.
What is to be displayed is slightly different depending on the orientation
ie: portrait won't have some extra panels and some stuff has to be moved around.
I need to access the view programmatically.
When accessing 'layout' I get a NullPointerException
each layout orientation has different ids ending in "_p" or "_l" in the xml file to differentiate whether portrait or landscape, when accessing them in java.
Both xml files are currently LinearLayout->TextView
Either way I cant get them to draw
I am using a thread and a clock to handle the drawing calls. Like in a game.
This is needed for doing some various custom animations.
I don't even think the background is drawing.
If I change from LinearLayout and call the TextView directly by its id
it runs without error, but nothing draws.
Try to remove android:configChanges attribute.
It'd be better not to use android:configChanges attribute.
Please refer to Android Developers Site in details
Caution: Handling the configuration change yourself can make it much more difficult to
use alternative resources, because the system does not automatically apply them for you. This technique should be considered a last resort when you must avoid restarts due to a configuration change and is not recommended for most applications.
https://developer.android.com/guide/topics/resources/runtime-changes
When turn the switch on it stays on.. however when i leave the activity and come back to it.. it goes back to off. I want it to stay ON OR OFF depending on whats last pressed. I have tried the code below but does not resolve my issue
SwitchButton.setChecked(true);
SwitchButton.setChecked(false);
What you need to do is override these methods in your activity:
#Override
protected void onSaveInstanceState (Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean("CHECKED", SwitchButton.isChecked());
}
then in onCreate:
#Override
protected void onCreate (Bundle savedInstanceState){
super.onCreate(savedInstaceState);
if(savedInstanceState != null){
boolean isChecked = savedInstanceState.getBoolean("CHECKED");
SwitchButton.setChecked(isChecked);
}
}
If you are minimizing the activity and then returning back to it, and you want all controls to retain their states, then look into implementing saved instance state. This will persist the control values while you minimize / maximize the activity or rotate it. No data is permanently saved to the device. Sample code here:
http://developer.android.com/training/basics/activity-lifecycle/recreating.html#SaveState
If you are closing the app completely and want the app to remember the settings, then consider SharedPreferences, which can be used to save data locally on the device. The data persists until your app explicitly deletes it or you uninstall the app. Sample code here:
http://developer.android.com/training/basics/data-storage/shared-preferences.html
I have an application that helps users organize prescriptions. I have one listview that shows medications and I use an EditText to allow the user to filter the list. The problem I'm having is that the CursorLoader is replaced each time the orientation changes.
From what I understand, the LoaderManager.initLoader() function should be called in onActivityCreated(). In my particular case, I don't have a fragment so I put the initLoader() call inside onPostCreate():
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
getSupportLoaderManager().initLoader(MEDICATION_LOADER, null, this);
}
And here is the filter I'm using:
// Set text filter
mMedication.addTextChangedListener(new TextWatcher() {
#Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
mMedicationAdapter.getFilter().filter(s);
}
});
I removed the empty beforeTextChanged and afterTextChanged methods to shorten this.
So, what appears to be happening (from using the debugger) is that each time I change the device orientation, initLoader() is called again and the entire list of medications are displayed, not just the filtered ones. Is there a way to implement onSaveInstanceState() to store the current filtered state of the adapter?
Or am I using the text filter wrong? Should I pass the charSequence as a Bundle argument to the loader, or create another loader that handles the text as an argument?
A solution is you can keep the current activity when orientation changes, Just set the Activity to handle config changes in AndroidManifest.xml:
Android config changes
e.g.
<activity
android:name="com.test.MyActivity"
android:configChanges="screenSize|orientation"/>
If your edittext was inflated through a layout file and it has an id; the framework should be automatically save its text.
You could try checking right before you attach your textwatcher, if the edittext has any text inside, then filter your list and then attach your textwatcher.
i have an app that has three pages, one of them is the main page. the user can enter in a few fields that i would like to save if the user goes to one of the two sub pages. i have been looking into the onPause() and into onSaveInstanceState(). i guess i just want a clear explanation on the two, and if onPause() is better and example of the code. this is what i ahve for onSaveInstanceState().
protected void onSaveInstanceState(Bundle outState) {
// Save away the original text, so we still have it if the activity
// needs to be killed while paused.
outState.putDouble("quizPts",qpts);
outState.putDouble("quizV",qvalue);
outState.putDouble("tPts",tpts);
outState.putDouble("tValue", tvalue);
outState.putDouble("hPts", hpts);
so that is how i am setting up bundle, by giving it an ID and a value.
public void onRestoreInstanceState(Bundle outState) {
super.onRestoreInstanceState(outState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
qpts = outState.getDouble("quizPts");
qvalue = outState.getDouble("quizV");
tpts = outState.getDouble("tPts");
tvalue = outState.getDouble("tValue");
hpts = outState.getDouble("hPts");
this is how i plan to retore it, the problem is i dont understand how to pass the Bundle around to restore it. i am setting the variables that i need to back to the variables that get set to the UI.
any advice would be great
thanks from a beginner androider
The best option will be a shared preference. The onpause is designed for attending your concerns when app is paused due to a phone call or something. But if you use shared preference it gives you the method for saving your data and recover it wit default values if the saved value is not available. This data will persist across user sessions (even if your application is killed). But it is not a good option if you are planning to save something other than primitive data types like bool,int etc.
see http://developer.android.com/guide/topics/data/data-storage.html#pref
You don't need to pass the bundle around yourself: the Activity framework takes care of that. Use onSaveInstanceState(): if your Activity class is destroyed for any reason by the system it will be called so you should be fine putting your logic in there. onPause will always be called if you leave your Activity, regardless of if the Activity is destroyed.
I would also add a check in your onRestoreInstanceState:
public void onRestoreInstanceState(Bundle outState) {
super.onRestoreInstanceState(outState);
// Restore UI state from the savedInstanceState.
// This bundle has also been passed to onCreate.
if(outState.containsKey("quizPts")) qpts = outState.getDouble("quizPts");
if(outState.containsKey("quizV")) qvalue = outState.getDouble("quizV");
if(outState.containsKey("tPts")) tpts = outState.getDouble("tPts");
if(outState.containsKey("tValue")) tvalue = outState.getDouble("tValue");
if(outState.containsKey("hPts")) hpts = outState.getDouble("hPts");