Restaurando o estado de TextView após a rotação da tela?


104

No meu aplicativo eu tenho TextViewe EditText. Ambos contêm dados. Quando a orientação da tela muda, os dados EditTextpermanecem, mas os TextViewdados são apagados.

Alguém pode me ajudar a encontrar uma maneira de reter dados TextViewtambém?

Respostas:


221

Se você deseja forçar seu TextViewa salvar seu estado, deve adicionar o freezesTextatributo:

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

Da documentação em freezesText:

Se definido, a visualização de texto incluirá seu texto completo atual dentro de seu icicle congelado, além de metadados, como a posição atual do cursor. Por padrão, isso está desabilitado; pode ser útil quando o conteúdo de uma visualização de texto não é armazenado em um local persistente, como um provedor de conteúdo


13
Por que o texto não é 'congelado / salvo' por padrão como outros atributos (seleção de texto, posição do cursor, etc.)? Em outras palavras, em que cenário alguém preferiria que o texto não fosse salvo?
Gautam

3
@Gautam, meu palpite seria que muitas vezes os TextViews são construídos a partir de strings estáticas armazenadas em XML, caso em que é redundante para o sistema lembrar os valores.
anderspitman

3
Na verdade, uma vez que você dê ao EditText ou TextView um id, o valor irá persistir durante um evento de rotação da tela.
DoctorFox

7
@jegesh - infelizmente este não é o caso para TextViews pelo menos em alguns dispositivos (Jellybean)
Bö macht Blau

1
Não funciona para mim, pelo menos não em um dispositivo API 17
Ab

28

Para reter dados sobre a mudança de orientação, você precisa implementar os dois métodos:

@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
Por que usar onRestoreInstanceState quando o mesmo pacote está disponível em onCreate?
slott

4
@slott Verifique esta documentação. developer.android.com/training/basics/activity-lifecycle/… Isso é conjectura, mas eu suspeito que seja porque o sistema monitora se está criando uma nova atividade ou recriando uma antiga. onRestorySavedInstance é chamado apenas em circunstâncias mais raras - alterações de configuração e destruição de atividade devido a limitações de memória.
Gusdor

6

1) Nem todas as visualizações com um ID salvam seu estado. Widgets Android, com um ID, cujo estado pode ser alterado pelo usuário, parecem salvar seu estado em um soft kill. Portanto, EditText salva seu estado, mas TextView não salva seu estado em um soft kill.

"AFAIK, o Android só se preocupa em salvar o estado de coisas que devem mudar. É por isso que ele salva o texto em um EditText (que é provável que o usuário altere) e talvez não salve o estado de um TextView (que normalmente permanece estático ) "

Mark M

Portanto, você pode escolher salvar o estado da visualização de texto em onSaveInstanceState e pode escolher restaurar o estado da visualização de texto em onCreate.

2) A prática recomendada é salvar o estado "interno" da instância sem visualização, mesmo se você declarar

android:configChanges= "orientation|keyboardHidden" 

Dos documentos:

"No entanto, seu aplicativo deve ser sempre capaz de desligar e reiniciar com seu estado anterior intacto. Não apenas porque há outras alterações de configuração que você não pode impedir de reiniciar seu aplicativo, mas também para lidar com eventos como quando o usuário recebe uma mensagem chamada telefônica e depois retorna ao seu aplicativo. "

JAL


6

O Android não cuida desse tipo de coisa para você. Você salvou todos os dados manualmente.

Você pode usar em uma atividade para salvar valores

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

e usar algo assim no método oncreate de uma atividade para carregar os objetos salvos

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

você também pode escolher desativar a mudança de orientação para uma atividade

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>

não pode substituir onRetainNonConfigurationInstance () em android.support.v4.app.fragmentActivity; o método substituído é final !!
Akash Dubey de

1

Modifique suas atividades em AndroidManifest.xml para substituir o comportamento de mudança de orientação, adicionando isto às suas atividades / atividades:

android:configChanges="orientation|keyboardHidden"

Deve ser parecido com isto:

    <activity android:name=".activity.LoginActivity"
              android:configChanges="orientation|keyboardHidden"
              android:label="@string/app_name">
    </activity>

27
Em geral, essa abordagem não é recomendada pela documentação : "O uso deste atributo deve ser evitado e usado apenas como último recurso. Leia Manipulando alterações de tempo de execução ..."
idbrii

1

Adicione-os a AndroidManifest.xml.
Coloque o nome da atividade no lugar de Activity_Name

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

Isso funcionará com a alteração de valor de TextField também.


1

apenas adicione

android:configChanges="orientation|screenSize"

à sua atividade em AndroidManifest.xml.


-2

Quando a configuração muda, o Android reinicia sua atividade por padrão. Para mudar isso, você deve substituir o onConfigurationChanged()método. Além disso, você deve adicionar android:configChangesao seu arquivo de manifesto.

Você pode ler mais aqui .


-7

Eu também usei

android:configChanges="orientation"

e não funcionou.

Mas então encontrei uma solução.

Verifique se você tem a seguinte linha corretamente em seu maniest:

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

certifique-se de que não leia algo como

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

Eu usei a segunda maneira em primeiro lugar, mas quando corrigi o estado foi preservado.


1
Isso é uma coisa completamente diferente. O objetivo do SDK é tornar seu aplicativo compatível com a maioria dos sistemas operacionais Android. Isso não é uma resposta, de alguma forma isso pode ter funcionado no seu caso, mas não é uma solução apropriada.
Rohan Kandwal
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.