EditText not automatically saved on screen orientation change
Asked Answered
C

5

13

I read that Android automatically saves the content of EditText objects when an application is about to be stopped or killed. However, in my app the content of an EditText is lost when screen orientation changes.

Is it normal behaviour? Do I then have to manually save/restore its content with onSaveInstanceState/onRestoreInstanceState? Or is there an easier method to tell Android to save it end restore it?

Edit:

I create the EditText object programmatically, not in XML. This turns out to be related to the problem (see accepted answer below).

Cog answered 7/10, 2013 at 20:59 Comment(0)
I
29

This is not normal behavior.

First and foremost, ensure that you have IDs assigned to your EditText controls in the layout XML.

Edit 1: It just needs an ID, period. If you're doing this programmatically, it will lose state unless it has an ID.

So using this as a quick & dirty example:

    // Find my layout
    LinearLayout mLinearLayout = (LinearLayout) findViewById(R.id.ll1);
    // Add a new EditText with default text of "test"
    EditText testText = new EditText(this.getApplicationContext());
    testText.setText("test");


    // This line is the key; without it, any additional text changes will 
    // be lost on rotation. Try it with and without the setId, text will revert
    // to just "test" when you rotate.

    testText.setId(100); 

    // Add your new EditText to the view.
    mLinearLayout.addView(testText);

That will solve your problem.

Should that fail, you'll need to save and restore state yourself.

Override onSaveInstanceState like so:

@Override
protected void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    outState.putString("textKey", mEditText.getText().toString());
}

And then restore in OnCreate:

public void onCreate(Bundle savedInstanceState) {
    if(savedInstanceState != null)
    {
        mEditText.setText(savedInstanceState.getString("textKey"));
    }
}

Also, please don't use android:configChanges="orientation" to try to accomplish this, it's the wrong way to go.

Intrastate answered 7/10, 2013 at 21:18 Comment(5)
Thanks. I am creating this editText in Java (programmatically ), not in XML. So the editText doesn't have an XML ID. Could that be the reason? Android won't save views that have been created programmatically? It does save, however, the state of a radioGroup which was also created programmatically. WeirdCog
Sorry about the confusion: the radioGroup state is actually saved through some code of mine (which saves and then retrieves app preferences), not by the system. I have removed that code and checked that the system does not save the state of that view either. So that must be the reason: programmatically created views don't have an XML ID and therefore are not automatically saved. What do you think? Does it make sense?Cog
It just needs an ID, period! Check my edit and if it works, accept the answer please. :)Intrastate
Problem solved, thanks! I didn't know how to assign an ID in JavaCog
Create a static property static int testTextId = View.generateViewId() and then use it in testText.setId(ClassName.testTextId). That way you don't have to invent a hardcoded ID integer.Mcneil
A
2

could you use android:freezesText="true" in the xml layout?

Anastaciaanastas answered 7/10, 2013 at 21:49 Comment(2)
Thanks for the suggestion. I create the editText in Java, not in XML. I tried editText.setFreezesText(true); but it doesn't work.Cog
This is a bit nuanced, but you really only need to use freezesText for a TextView, not for EditText. Android only seems to bother saving state for items that are likely to change; EditText is designed to be edited, so as long as it has an ID, Android will save state on a soft kill (though not a hard exit). TextView is the opposite, so it makes sense to explicitly persist state if needed there.Intrastate
V
2

The easiest way I found to save an object on onSaveInstanceState is to implement serializable and put in bundle

@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putSerializable("myObj", myObj);
}

where myObj class implements serializable and in onCreate() method

if (savedInstanceState != null && savedInstanceState.getSerializable("myObj") != null) {
myObj = ((MyObj) savedInstanceState.getSerializable("myObj"));
}
Voodooism answered 21/2, 2014 at 6:34 Comment(1)
Thanks. Actually I wanted Android to do that for me. It turns out that assigning an ID to the object is enough to get Android doing the work (See Mike P.'s answer)Cog
P
2

One possible cause is that you override onSaveInstanceState but you forget to call the same for super class

super.onSaveInstanceState(outState);

State of all views in activity is auto saved UNLESS you override this functionality. Even if this is obvious, mistakes are possible.

Prophecy answered 19/5, 2016 at 6:36 Comment(1)
Actually my problem was that the object didn't have an ID, because I was creating it in Java, not in XML. But thanks for the idea; it may be useful for othersCog
S
2

You just need UNIQUE ID for the edit text. Make sure if you dynamically add edit text, chances of having same id can cause not restoring the text. Same way if you add in xml, use unique id. Hope it will help someone.

FYI: EditText by default having setFreezesText as true

Scoliosis answered 27/4, 2022 at 11:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.