Przywracasz stan TextView po obróceniu ekranu?

104

W mojej aplikacji mam TextViewi EditText. Oba zawierają dane. Gdy orientacja ekranu zmienia dane w EditTextpozostałości, ale TextViewdane są usuwane.

Czy ktoś może mi pomóc znaleźć sposób na przechowywanie danych TextView?

kAnNaN
źródło

Odpowiedzi:

221

Jeśli chcesz wymusić TextViewzapisanie swojego stanu musisz dodać freezesTextatrybut:

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

Z dokumentacji freezesText:

Jeśli jest ustawiona, widok tekstu będzie zawierał swój bieżący pełny tekst wewnątrz zamrożonego sopla oprócz metadanych, takich jak bieżąca pozycja kursora. Domyślnie jest to wyłączone; może być przydatne, gdy zawartość widoku tekstu nie jest przechowywana w trwałym miejscu, takim jak dostawca treści

inazaruk
źródło
13
Dlaczego tekst nie jest domyślnie „zamrożony / zapisany” jak inne atrybuty (zaznaczenie tekstu, pozycja kursora itp.)? Innymi słowy, w jakim scenariuszu ktoś faktycznie wolałby , aby tekst nie został zapisany?
Gautam
3
@Gautam domyślam się, że często TextViews są budowane ze statycznych ciągów zapisanych w XML, w takim przypadku zapamiętywanie wartości jest zbędne dla systemu.
anderspitman
3
Właściwie po nadaniu EditText lub TextView identyfikatora wartość będzie się utrzymywać podczas zdarzenia obracania ekranu.
DoctorFox,
7
@jegesh - niestety tak nie jest w przypadku TextViews przynajmniej na niektórych urządzeniach (Jellybean)
Bö macht Blau
1
Nie działa dla mnie, przynajmniej nie na urządzeniu API 17
Ab
28

Aby zachować dane o zmianie orientacji, musisz wdrożyć dwie metody:

@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
źródło
5
Po co używać onRestoreInstanceState, skoro ten sam pakiet jest dostępny w onCreate?
slott
4
@slott Sprawdź tę dokumentację. developer.android.com/training/basics/activity-lifecycle/… To przypuszczenie, ale podejrzewam, że dzieje się tak, ponieważ system śledzi, czy tworzy nowe działanie, czy odtwarza stare. onRestorySavedInstance jest wywoływana tylko w rzadszych przypadkach - zmiany konfiguracji i zniszczenie aktywności z powodu ograniczeń pamięci.
Gusdor,
6

1) Nie wszystkie widoki z identyfikatorem zapisują swój stan. Widżety Androida z identyfikatorem, którego stan może zmienić użytkownik, wydają się zapisywać swój stan po miękkim zabiciu. Więc EditText zapisuje swój stan, ale TextView nie zapisuje swojego stanu po miękkim zabiciu.

„AFAIK, Android zajmuje się zapisywaniem stanu tylko dla rzeczy, które mają się zmienić. Dlatego zapisuje tekst w EditText (który użytkownik prawdopodobnie zmieni) i być może nie zapisuje stanu dla TextView (który zwykle pozostaje statyczny ) ”

Mark M.

Możesz więc zdecydować się na zapisanie stanu widoku tekstu w onSaveInstanceState i możesz wybrać przywrócenie stanu widoku tekstu w onCreate.

2) Najlepszą praktyką jest zapisanie „wewnętrznego” stanu wystąpienia bez widoku, nawet jeśli zadeklarujesz

android:configChanges= "orientation|keyboardHidden" 

Z dokumentów:

„Jednak aplikacja powinna zawsze mieć możliwość zamykania i ponownego uruchamiania z nienaruszonym poprzednim stanem. Nie tylko z powodu innych zmian w konfiguracji, którym nie można zapobiec przed ponownym uruchomieniem aplikacji, ale także w celu obsługi zdarzeń, takich jak otrzymanie przez użytkownika przychodzącego rozmowa telefoniczna, a następnie wraca do aplikacji ”.

JAL

JAL
źródło
6

Android nie obsługuje tego typu rzeczy za Ciebie. Zapisałeś wszystkie dane ręcznie.

Możesz użyć w działaniu, aby zapisać wartości

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

i użyj czegoś takiego w metodzie oncreate działania, aby załadować zapisane obiekty

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

możesz również wybrać opcję wyłączenia zmiany orientacji dla działania

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>
Kevin
źródło
nie można zastąpić onRetainNonConfigurationInstance () w android.support.v4.app.fragmentActivity; zastąpiona metoda jest ostateczna !!
Akash Dubey
1

Zmodyfikuj swoje działania w AndroidManifest.xml, aby nadpisać zachowanie zmiany orientacji, dodając to do swojej aktywności / działań:

android:configChanges="orientation|keyboardHidden"

Powinien wyglądać mniej więcej tak:

    <activity android:name=".activity.LoginActivity"
              android:configChanges="orientation|keyboardHidden"
              android:label="@string/app_name">
    </activity>
Joakim Berglund
źródło
27
Ogólnie rzecz biorąc, takie podejście nie jest zalecane w dokumentacji : "Należy unikać używania tego atrybutu i używać go tylko w ostateczności. Przeczytaj artykuł Obsługa zmian w czasie wykonywania ..."
idbrii
1

Dodaj je do pliku AndroidManifest.xml
Umieść nazwę działania w miejscu nazwa_działania

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

Będzie to działać również w przypadku zmiany wartości TextField.

Rahul Krishna
źródło
1

poprostu dodaj

android:configChanges="orientation|screenSize"

do swojej aktywności w AndroidManifest.xml.

farhad.kargaran
źródło
-2

Po zmianie konfiguracji Android ponownie uruchamia Twoją aktywność domyślnie. Aby to zmienić, należy zastąpić onConfigurationChanged()metodę. Powinieneś także dodaćandroid:configChanges do pliku manifestu.

Możesz przeczytać więcej tutaj .

Vladimir Ivanov
źródło
-7

Użyłem też

android:configChanges="orientation"

i to nie zadziałało.

Ale potem znalazłem rozwiązanie.

Sprawdź, czy masz następujący wiersz poprawnie w swoim pierwszym:

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

upewnij się, że nie ma czegoś takiego jak

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

Miałem to na drugim miejscu, ale po poprawieniu stan został zachowany.

Optimus
źródło
1
To jest zupełnie inna sprawa. Docelowy pakiet SDK ma zapewnić zgodność aplikacji z większością systemów operacyjnych Android. To nie jest odpowiedź, pod pewnymi względami mogło to zadziałać w twoim przypadku, ale nie jest to właściwe rozwiązanie.
Rohan Kandwal,