EditText не сохраняется автоматически при изменении ориентации экрана

Я читал, что Android автоматически сохраняет содержимое объектов EditText, когда приложение собирается остановить или убить. Однако в моем приложении содержимое EditText теряется при изменении ориентации экрана.

Это нормальное поведение? Должен ли я вручную сохранять/восстанавливать его содержимое с помощью onSaveInstanceState/onRestoreInstanceState? Или есть более простой способ сказать Android, чтобы сохранить его, восстановить его?

Edit

Я создаю объект EditText программно, а не в XML. Это оказывается связанным с проблемой (см. Принятый ответ ниже).

Ответ 1

Это не нормальное поведение.

Прежде всего, убедитесь, что у вас есть идентификаторы, назначенные вашим элементам EditText в XML-макете.

Изменить 1: Ему просто нужен идентификатор, период. Если вы делаете это программно, оно потеряет состояние, если оно не имеет идентификатора.

Таким образом, используя это как быстрый и грязный пример:

    // 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);

Это решит вашу проблему.

Если это не удастся, вам нужно сохранить и восстановить состояние самостоятельно.

Переопределить onSaveInstanceState следующим образом:

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

И затем восстановите в OnCreate:

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

Кроме того, не используйте android:configChanges="orientation", чтобы попытаться это сделать, это неправильный путь.

Ответ 2

Самый простой способ, которым я нашел сохранение объекта onSaveInstanceState, - реализовать сериализуемое и вставить в пакет

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

где класс myObj реализует serializable и метод onCreate()

if (savedInstanceState != null && savedInstanceState.getSerializable("myObj") != null) {
myObj = ((MyObj) savedInstanceState.getSerializable("myObj"));
}

Ответ 3

Вы могли бы использовать android:freezesText="true" в макете xml?

Ответ 4

Одна из возможных причин заключается в том, что вы переопределяете onSaveInstanceState, но вы забываете называть то же самое для суперкласса

super.onSaveInstanceState(outState);

Состояние всех представлений в действии автоматически сохраняется, ЕСЛИ вы переопределите эту функциональность. Даже если это очевидно, возможны ошибки.