Відновлення стану TextView після обертання екрана?


104

У своєму додатку у мене є TextViewі EditText. У обох є дані. Коли орієнтація екрана змінює дані в EditTextзалишках, але TextViewдані видаляються.

Чи може хтось допомогти мені знайти спосіб збереження даних TextView?

Відповіді:


221

Якщо ви хочете змусити TextViewзберегти його стан, ви повинні додати freezesTextатрибут:

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

З документації на freezesText:

Якщо встановлено, подання тексту буде включати його поточний повний текст всередині його замороженої бурульки на додаток до метаданих, таких як поточне положення курсору. За замовчуванням це вимкнено; він може бути корисним, коли вміст перегляду тексту не зберігається в постійному місці, наприклад постачальнику вмісту


13
Чому текст "заморожений / збережений" за замовчуванням не є таким, як інші атрибути (вибір тексту, положення курсору тощо)? Іншими словами, за якого сценарію хтось насправді вважає за краще, щоб текст не був збережений?
Гаутам

3
@Gautam гадаю, що часто TextViews будуються зі статичних рядків, що зберігаються в 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?
слот

4
@slott Перевірте цю документацію. developer.android.com/training/basics/activity-lifecycle/… Це припущення, але я підозрюю, що це відбувається тому, що система відстежує, чи створює нову діяльність, чи відтворює стару. onRestorySavedInstance викликається лише в більш рідкісних обставинах - зміни конфігурації та знищення активності через обмеження пам'яті.
Гусдор

6

1) Не всі перегляди з ідентифікатором зберігають свій стан. Android-віджети з ідентифікатором, стан якого може бути змінений користувачем, схоже, врятують їх стан при знищенні програмного забезпечення. Таким чином, EditText зберігає свій стан, але TextView не зберігає свій стан при м'якому знищенні.

"AFAIK, Android турбує стан збереження лише для речей, які, як очікується, зміниться. Ось чому він зберігає текст у EditText (який користувач може змінити) і, можливо, не зберігає стан для TextView (який зазвичай залишається статичним ) "

Марк М

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

2) Найкраща практика - збереження "внутрішнього" стану екземпляра без перегляду, навіть якщо ви заявляєте

android:configChanges= "orientation|keyboardHidden" 

З документів:

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

JAL


6

Android не обробляє такі речі для вас. Ви збережете всі дані вручну.

Ви можете використовувати в діяльності для збереження значень

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

і використовувати щось подібне у створеному методі діяльності для завантаження збережених об'єктів

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; метод переопределення остаточний !!
Акаш Дюбей

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.


-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. Це не відповідь, якимось чином це може спрацювати у вашому випадку, але це не є прийнятним рішенням.
Rohan Kandwal
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.