109

In my app I have TextView and EditText. Both have data in it. When the screen orientation changes the data in the EditText remains, but TextView data is cleared.

Can some one help me out to find a way to retain data in TextView too?

Willi Mentzel
  • 27,862
  • 20
  • 113
  • 121
kAnNaN
  • 3,669
  • 4
  • 28
  • 39

9 Answers9

229

If you want to force your TextView to save its state you must add freezesText attribute:

<TextView 
     ... 
     android:freezesText="true" />

From documentation on freezesText :

If set, the text view will include its current complete text inside of its frozen icicle in addition to meta-data such as the current cursor position. By default this is disabled; it can be useful when the contents of a text view is not stored in a persistent place such as a content provider

inazaruk
  • 74,247
  • 24
  • 188
  • 156
  • @kAnNaN: I think you should accept this answer as a solution. – Vit Khudenko Jul 13 '12 at 21:29
  • 13
    Why isn't the text 'frozen/saved' by default like other attributes (text selection, cursor position, etc.)? In other words, in what scenario would someone actually _prefer_ that the text is _not_ saved? – Gautam Oct 13 '13 at 09:18
  • Is there a way to set this globally across the application? In the manifest maybe? Or at least in the view? – Tamby Kojak Apr 15 '14 at 19:28
  • 3
    @Gautam my guess would be that often TextViews are built from static strings stored in XML, in which case it's redundant for the system to remember the values. – anderspitman Jul 31 '14 at 01:24
  • 3
    Actually, once you give the EditText or TextView an id the value will persist during a screen rotation event. – DoctorFox Jun 15 '15 at 00:58
  • 7
    @jegesh - unfortunately this is not the case for TextViews at least on some devices (Jellybean) – Bö macht Blau Jan 15 '16 at 09:34
  • 1
    Doesn't work for me, at least not on an API 17 device – Ali Bdeir Aug 02 '16 at 18:58
  • @Guatam, the real reason why you don't want this to happen automatically is that a TextView can store very very complicated text (spans). Spans can hold references to activities have click listeners and other complicated things. You can't simply save those things. Also custom spans can't be restored by the system. – Rolf ツ Feb 15 '18 at 13:57
28

In order to retain data on orientation change you need to implement the two methods:

@Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
    super.onRestoreInstanceState(savedInstanceState);
    // Read values from the "savedInstanceState"-object and put them in your textview
}

@Override
protected void onSaveInstanceState(Bundle outState) {
    // Save the values you need from your textview into "outState"-object
    super.onSaveInstanceState(outState);
}
Eric Nordvik
  • 14,656
  • 8
  • 42
  • 50
  • 5
    Why use onRestoreInstanceState when the same bundle is available in onCreate ? – slott May 24 '12 at 07:14
  • 5
    @slott Check this documentation. http://developer.android.com/training/basics/activity-lifecycle/recreating.html This is conjecture but I suspect it is because the system keeps track of if it is creating a new activity, or recreating an old one. onRestorySavedInstance is only called in rarer circumstances - configuration changes and activity destruction due to memory limitations. – Gusdor Jun 14 '12 at 15:34
6

Android does not handle that kind of stuff for you. You have save all data manually.

You can use in a activity to save values

@Override
    public Object onRetainNonConfigurationInstance() {
        HashMap<String, Object> savedValues = new HashMap<String, Object>();
        savedValues.put("someKey", someData);           
        return savedValues;
    }

and use something like this in the oncreate method of a activity to load the saved objects

HashMap < String, Object> savedValues 
     = (HashMap<String, Object>)this.getLastNonConfigurationInstance();

you can also choose the disable orientation change for an activity

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>
pablisco
  • 14,027
  • 4
  • 48
  • 70
Kevin
  • 1,745
  • 13
  • 16
  • cannot override onRetainNonConfigurationInstance() in android.support.v4.app.fragmentActivity;overridden method is final!! – Akash Dubey Nov 16 '16 at 08:10
6

1) Not all views with an ID save their state. Android widgets, with an ID, whose state can be changed by the user, appear to save their state on a soft kill. So EditText saves its state, but TextView does not save its state on a soft kill.

"AFAIK, Android only bothers saving state for things that are expected to change. That is why it saves the text in an EditText (which a user is likely to change) and perhaps does not save the state for a TextView (which normally stays static)"

Mark M

So you may choose to save the state of the textview in onSaveInstanceState and you may choose to restore the state of the textview in onCreate.

2) Best practice is to save "internal" non view instance state even if you declare

android:configChanges= "orientation|keyboardHidden" 

From the docs:

"However, your application should always be able to shutdown and restart with its previous state intact. Not only because there are other configuration changes that you cannot prevent from restarting your application but also in order to handle events such as when the user receives an incoming phone call and then returns to your application."

JAL

JAL
  • 3,319
  • 2
  • 20
  • 17
1

Add these to AndroidManifest.xml
Put your Activity Name in the place of Activity_Name

<activity android:name="Activity_Name"
        android:screenOrientation="sensor"
        ...
        android:configChanges="orientation|keyboardHidden|screenSize">

This will work with value changing TextField also.

Rahul Krishna
  • 103
  • 1
  • 11
1

Modify your activities in AndroidManifest.xml to override orientation change behavior by adding this to your activity/activities:

android:configChanges="orientation|keyboardHidden"

It should look somewhat like this:

    <activity android:name=".activity.LoginActivity"
              android:configChanges="orientation|keyboardHidden"
              android:label="@string/app_name">
    </activity>
Joakim Berglund
  • 2,859
  • 1
  • 22
  • 30
  • 27
    In general, this approach [isn't recommended by the documentation](http://developer.android.com/guide/topics/manifest/activity-element.html#config): "Using this attribute should be avoided and used only as a last-resort. Please read [Handling Runtime Changes](http://developer.android.com/guide/topics/resources/runtime-changes.html)..." – idbrii Jun 17 '11 at 20:51
1

just add

android:configChanges="orientation|screenSize"

to your Activity in AndroidManifest.xml.

farhad.kargaran
  • 2,233
  • 1
  • 24
  • 30
-2

When configuration changes Android restarts your activity by default. To change this you should override onConfigurationChanged() method. Also, you should add android:configChanges to your manifest file.

You can read more here.

Vladimir Ivanov
  • 42,730
  • 18
  • 77
  • 103
-7

I also used

android:configChanges="orientation"

and it did not work.

But then I found a solution.

Verify if you have the following line correctly in your maniest:

<uses-sdk android:minSdkVersion="11" android:targetSdkVersion="11" />

make sure it does not read something like

<uses-sdk android`:minSdkVersion="11" android:targetSdkVersion="15" />`

I had it the second way in first place but when I corrected it state got preserved.

Stephan
  • 41,764
  • 65
  • 238
  • 329
Optimus
  • 15
  • 1
  • 8
  • 1
    This is a completely different thing. Target SDK is to make your app compatible with most ranges of Android OS. This is not an answer, by some means this may have worked in your case but this is not an appropiate solution. – Rohan Kandwal Jul 06 '13 at 17:03