13

My understanding was that all standard Views with an ID should save their state automatically, and upon trying this on an example I found it to be quite confusing.

I had only 1 activity and the main layout as listed below.
When I change the text of the TextView by clicking on the button, and then rotate the screen, the TextView does actually save it's state, but upon rotating again, it resets to it's default state.

Same happens if I edit it while in landscape and rotate: after first rotate it still saves it's state, but after another rotate (unless I change the text again) it resets to default value.

I'm really confused now. Could someone please explain this behavior to me. I wasn't able to find any other question (or answer) that explains this specific behavior.

activity_main.xml:

<RelativeLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/activity_main_textView"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:maxLines="2"
        android:text="test"
        android:textSize="50sp"
        />

    <EditText
        android:id="@+id/activity_main_editText"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_centerVertical="true"
        android:maxLength="30"
        android:maxLines="1"
        />

    <Button
        android:id="@+id/activity_main_button"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:text="Set text"
        />

</RelativeLayout>

MainActivity.java:

package com.example.viewstatetest;

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private EditText editText;
    private View button;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        textView = (TextView) findViewById(R.id.activity_main_textView);
        editText = (EditText) findViewById(R.id.activity_main_editText);
        button = findViewById(R.id.activity_main_button);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                textView.setText(editText.getText());
            }
        });
    }
}
SuperLemon
  • 751
  • 1
  • 7
  • 23
  • Try this maybe: http://stackoverflow.com/questions/5123407/losing-data-when-rotate-screen – Zarwan Jul 21 '15 at 02:09
  • Thanks but that shows how to save the state. I know how to manually save the state, but would like to know why some Views (sometimes!) won't save their state automatically. – SuperLemon Jul 21 '15 at 11:56

1 Answers1

21

If you look at the TextView sources (in particular TextView#onSaveInstanceState()), you will see that text is saved only in two cases:

  1. When user explicitly asked to do that by setting freezeText flag to true via android:freezesText="true" or TextView#setFreezesText(true)
  2. When text within TextView has selection.

In your case both of these cases are false, so your text gets reset to its default state during orientation change.

Simple change to your layout will solve the issue:

<TextView
    android:id="@+id/activity_main_textView"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:freezesText="true"
    android:maxLines="2"
    android:text="test"
    android:textSize="50sp"
    />
Pavel Dudka
  • 20,754
  • 7
  • 70
  • 83
  • 1
    Thank you very much! Is there any practical difference between freezing it and manually saving and restoring the text? Also how come in my example, the state is saved through the 1st orientation change, and resets only after the second one? Thanks again! – SuperLemon Jul 21 '15 at 15:12
  • 1
    @SuperLemon I don't think you need to reinvent the wheel for saving state manually, so I would use what's already available. As for why it saves state during first orientation change - I honestly don't know :) I created a test project with your layout and tried to reproduce this behavior - I lose my textview state during very first orientation change – Pavel Dudka Jul 22 '15 at 09:22