Восстановление состояния TextView после поворота экрана?

104

В моем приложении есть TextViewи EditText. У обоих есть данные. При изменении ориентации экрана данные EditTextостаются, но TextViewданные очищаются.

Может ли кто-нибудь помочь мне найти способ сохранить данные TextView?

КАННАН
источник

Ответы:

221

Если вы хотите заставить TextViewсохранить свое состояние, вы должны добавить freezesTextатрибут:

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

Из документации по freezesText:

Если установлено, текстовое представление будет включать свой текущий полный текст внутри своей замороженной сосульки в дополнение к метаданным, таким как текущая позиция курсора. По умолчанию это отключено; это может быть полезно, когда содержимое текстового представления не хранится в постоянном месте, таком как поставщик содержимого

Иназарук
источник
13
Почему текст по умолчанию не «заморожен / сохранен», как другие атрибуты (выделение текста, положение курсора и т. Д.)? Другими словами, в каком сценарии кто-то действительно предпочел бы , чтобы текст не сохранялся?
Гаутам
3
@Gautam, я предполагаю, что часто TextView строятся из статических строк, хранящихся в XML, и в этом случае система излишне запоминает значения.
anderspitman
3
Фактически, как только вы дадите EditText или TextView идентификатор, значение будет сохраняться во время события поворота экрана.
DoctorFox
7
@jegesh - к сожалению, это не относится к TextViews, по крайней мере, на некоторых устройствах (Jellybean)
Bö macht Blau
1
Не работает для меня, по крайней мере , не на API 17 устройства
Ab
28

Чтобы сохранить данные об изменении ориентации, вам необходимо реализовать два метода:

@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);
}
Эрик Нордвик
источник
5
Зачем использовать onRestoreInstanceState, если тот же пакет доступен в onCreate?
slott
4
@slott Проверьте эту документацию. developer.android.com/training/basics/activity-lifecycle/… Это предположение, но я подозреваю, что это связано с тем, что система отслеживает, создает ли она новую деятельность или воссоздает старую. onRestorySavedInstance вызывается только в более редких случаях - при изменении конфигурации и уничтожении активности из-за ограничений памяти.
Gusdor
6

1) Не все представления с идентификатором сохраняют свое состояние. Виджеты Android с идентификатором, состояние которого может быть изменено пользователем, по-видимому, сохраняют свое состояние при мягком уничтожении. Итак, EditText сохраняет свое состояние, но TextView не сохраняет свое состояние при мягком уничтожении.

"AFAIK, Android заботится о сохранении состояния только для вещей, которые, как ожидается, изменится. Вот почему он сохраняет текст в EditText (который пользователь может изменить) и, возможно, не сохраняет состояние для TextView (которое обычно остается статическим ) "

Марк М

Таким образом, вы можете сохранить состояние текстового представления в onSaveInstanceState, и вы можете выбрать восстановление состояния текстового представления в onCreate.

2) Лучше всего сохранять «внутреннее» состояние экземпляра без просмотра, даже если вы объявляете

android:configChanges= "orientation|keyboardHidden" 

Из документов:

«Однако ваше приложение всегда должно иметь возможность завершать работу и перезапускаться с сохранением предыдущего состояния. Не только потому, что есть другие изменения конфигурации, которые вы не можете предотвратить от перезапуска вашего приложения, но и для обработки таких событий, как получение пользователем входящего телефонный звонок, а затем вернется к вашему приложению ".

JAL

JAL
источник
6

Android не делает за вас такие вещи. Вы сохранили все данные вручную.

Вы можете использовать в действии для сохранения значений

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

и используйте что-то подобное в методе oncreate действия для загрузки сохраненных объектов

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

вы также можете выбрать отключение изменения ориентации для занятия

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>
Кевин
источник
не может переопределить onRetainNonConfigurationInstance () в android.support.v4.app.fragmentActivity; переопределенный метод является окончательным !!
Akash Dubey
1

Измените свои действия в AndroidManifest.xml, чтобы переопределить поведение изменения ориентации, добавив это в свое действие / действия:

android:configChanges="orientation|keyboardHidden"

Это должно выглядеть примерно так:

    <activity android:name=".activity.LoginActivity"
              android:configChanges="orientation|keyboardHidden"
              android:label="@string/app_name">
    </activity>
Йоаким Берглунд
источник
27
В общем, этот подход не рекомендуется в документации : «Следует избегать использования этого атрибута и использовать его только в крайнем случае. Пожалуйста, прочтите« Обработка изменений во время выполнения ... »
idbrii
1

Добавьте их в AndroidManifest.xml.
Поместите название вашей деятельности вместо Activity_Name.

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

Это также будет работать с изменением значения TextField.

Рахул Кришна
источник
1

просто добавь

android:configChanges="orientation|screenSize"

к вашей деятельности в AndroidManifest.xml.

farhad.kargaran
источник
-2

При изменении конфигурации Android по умолчанию перезапускает вашу активность. Чтобы изменить это, вы должны переопределить onConfigurationChanged()метод. Кроме того, вы должны добавить android:configChangesв свой файл манифеста.

Вы можете прочитать здесь .

Владимир Иванов
источник
-7

Я также использовал

android:configChanges="orientation"

и это не сработало.

Но потом я нашел решение.

Убедитесь, что у вас правильно написана следующая строка:

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

убедитесь, что он не читает что-то вроде

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

У меня на первом месте был второй способ, но когда я исправил, состояние сохранилось.

Оптимус
источник
1
Это совсем другое дело. Целевой SDK предназначен для обеспечения совместимости вашего приложения с большинством диапазонов ОС Android. Это не ответ, каким-то образом это могло сработать в вашем случае, но это неподходящее решение.
Рохан Кандвал 06