Restaurer l'état de TextView après la rotation de l'écran?

104

Dans mon application, j'ai TextViewet EditText. Les deux contiennent des données. Lorsque l'orientation de l'écran change les données dans les EditTextrestes, mais les TextViewdonnées sont effacées.

Quelqu'un peut-il aussi m'aider à trouver un moyen de conserver les données TextView?

kAnNaN
la source

Réponses:

221

Si vous voulez forcer votre TextViewà enregistrer son état, vous devez ajouter un freezesTextattribut:

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

De la documentation sur freezesText:

Si elle est définie, la vue texte comprendra son texte complet actuel à l'intérieur de son glaçon gelé en plus des méta-données telles que la position actuelle du curseur. Par défaut, cela est désactivé; cela peut être utile lorsque le contenu d'une vue de texte n'est pas stocké dans un endroit persistant tel qu'un fournisseur de contenu

inazaruk
la source
13
Pourquoi le texte n'est-il pas «figé / enregistré» par défaut comme les autres attributs (sélection de texte, position du curseur, etc.)? En d'autres termes, dans quel scénario quelqu'un préférerait-il réellement que le texte ne soit pas enregistré?
Gautam
3
@Gautam, je suppose que souvent les TextViews sont construits à partir de chaînes statiques stockées en XML, auquel cas il est redondant pour le système de se souvenir des valeurs.
anderspitman
3
En fait, une fois que vous avez donné un identifiant à EditText ou TextView, la valeur persistera pendant un événement de rotation d'écran.
DoctorFox
7
@jegesh - malheureusement ce n'est pas le cas pour TextViews au moins sur certains appareils (Jellybean)
Bö macht Blau
1
Ne fonctionne pas pour moi, au moins pas sur un périphérique API 17
Ab
28

Afin de conserver les données sur le changement d'orientation, vous devez implémenter les deux méthodes:

@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
la source
5
Pourquoi utiliser onRestoreInstanceState quand le même bundle est disponible dans onCreate?
slott
4
@slott Consultez cette documentation. developer.android.com/training/basics/activity-lifecycle/… C'est une conjecture mais je soupçonne que c'est parce que le système garde une trace de s'il crée une nouvelle activité ou recrée une ancienne. onRestorySavedInstance n'est appelé que dans des circonstances plus rares - changements de configuration et destruction d'activité en raison de limitations de mémoire.
Gusdor le
6

1) Toutes les vues avec un ID ne sauvegardent pas leur état. Les widgets Android, avec un identifiant, dont l'état peut être modifié par l'utilisateur, semblent enregistrer leur état lors d'un soft kill. Ainsi, EditText enregistre son état, mais TextView ne sauvegarde pas son état lors d'un arrêt logiciel.

"AFAIK, Android ne dérange l'enregistrement de l'état que pour les choses qui devraient changer. C'est pourquoi il enregistre le texte dans un EditText (qu'un utilisateur est susceptible de changer) et n'enregistre peut-être pas l'état pour un TextView (qui reste normalement statique ) "

Mark M

Vous pouvez donc choisir d'enregistrer l'état de la vue de texte dans onSaveInstanceState et vous pouvez choisir de restaurer l'état de la vue de texte dans onCreate.

2) La meilleure pratique consiste à enregistrer l'état d'instance "interne" sans vue même si vous déclarez

android:configChanges= "orientation|keyboardHidden" 

À partir de la documentation:

"Cependant, votre application doit toujours pouvoir s'arrêter et redémarrer avec son état précédent intact. Non seulement parce qu'il y a d'autres modifications de configuration que vous ne pouvez pas empêcher de redémarrer votre application, mais aussi afin de gérer des événements tels que lorsque l'utilisateur reçoit un message entrant appel téléphonique, puis revient à votre application. "

JAL

JAL
la source
6

Android ne gère pas ce genre de choses pour vous. Vous avez enregistré toutes les données manuellement.

Vous pouvez utiliser dans une activité pour enregistrer des valeurs

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

et utilisez quelque chose comme ça dans la méthode oncreate d'une activité pour charger les objets enregistrés

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

vous pouvez également choisir la désactivation du changement d'orientation pour une activité

<activity android:name=".Activity" android:screenOrientation="portrait" >
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
    </intent-filter>
</activity>
Kevin
la source
impossible de remplacer onRetainNonConfigurationInstance () dans android.support.v4.app.fragmentActivity; la méthode remplacée est définitive !!
Akash Dubey
1

Modifiez vos activités dans AndroidManifest.xml pour remplacer le comportement de changement d'orientation en ajoutant ceci à votre activité / activités:

android:configChanges="orientation|keyboardHidden"

Cela devrait ressembler un peu à ceci:

    <activity android:name=".activity.LoginActivity"
              android:configChanges="orientation|keyboardHidden"
              android:label="@string/app_name">
    </activity>
Joakim Berglund
la source
27
En général, cette approche n'est pas recommandée par la documentation : "L'utilisation de cet attribut doit être évitée et utilisée uniquement en dernier recours. Veuillez lire Gestion des modifications d'exécution ..."
idbrii
1

Ajoutez-les à AndroidManifest.xml
Mettez votre nom d'activité à la place de Activity_Name

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

Cela fonctionnera également avec le changement de valeur TextField.

Rahul Krishna
la source
1

il suffit d'ajouter

android:configChanges="orientation|screenSize"

à votre activité dans AndroidManifest.xml.

farhad.kargaran
la source
-2

Lorsque la configuration change, Android redémarre votre activité par défaut. Pour changer cela, vous devez remplacer la onConfigurationChanged()méthode. Vous devez également ajouterandroid:configChanges à votre fichier manifeste.

Vous pouvez en savoir plus ici .

Vladimir Ivanov
la source
-7

J'ai aussi utilisé

android:configChanges="orientation"

et cela n'a pas fonctionné.

Mais ensuite j'ai trouvé une solution.

Vérifiez si vous avez correctement la ligne suivante dans votre maniest:

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

assurez-vous qu'il ne lit pas quelque chose comme

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

Je l'ai eu la deuxième manière en premier lieu mais quand je l'ai corrigé, l'état a été préservé.

Optimus
la source
1
C'est une chose complètement différente. Le SDK cible est de rendre votre application compatible avec la plupart des gammes de systèmes d'exploitation Android. Ce n'est pas une réponse, par certains moyens, cela peut avoir fonctionné dans votre cas, mais ce n'est pas une solution appropriée.
Rohan Kandwal