Une bonne solution pour conserver les éléments listview lorsque l'utilisateur de faire pivoter le téléphone et conserver toutes les données ArrayAdapter
Je suis en utilisant le Fragment avec listView. - Je remplir ArrayAdapter associés à cette liste, par les données reçues dans le Chargeur personnalisé(de l'internet). Personnalisé ArrayAdapter prend en charge infini défilement(paging).
Quelle est la meilleure façon de stocker les éléments dans ArrayAdapter lorsque l'utilisateur de faire pivoter l'appareil et de conserver la position de défilement dans ListView?
Je suis en train de penser à propos de la création de la non-visuel Fragment avec ArrayAdapter, et à l'aide de setRetainInstance méthode pour enregistrer les valeurs.
Des suggestions pour une meilleure solution?
- developer.android.com/guide/topics/resources/...
- vous pouvez le vérifier pour des fragments androiddesignpatterns.com/2013/04/... vous pouvez vérifier l'onConfigurationChanged @ developer.android.com/reference/android/app/Fragment.html
- Vous faites le ArrayAdapter statique, dans le onCreate vérifier si il est nul, si c'créer d'autre appel d'invalider sur elle (à force de redessin)?
Vous devez vous connecter pour publier un commentaire.
De travail avec Android cadre et le Fragment du cycle de vie, vous devriez mettre en œuvre les
onSaveInstanceState
méthode dans votre Fragment. Pour des raisons de simplicité j'ai supposé que vous avez un tableau de valeurs de Chaîne que vous pouvez obtenir pour (je prolonge généralement ArrayAdapter pour encapsuler vue de la construction et de fournir une méthode pratique pour accéder à l'ensemble sous-jacent dataset):Vous pouvez ensuite récupérer les données dans votre méthode onCreate (ou onCreateView ou onActivityCreated - voir le Fragment JavaDoc) comme ceci:
Cela garantit que tous les événements de cycle de vie seront traitées correctement, sans perte de données, y compris le dispositif de rotation et le changement d'utilisateur vers d'autres applications. Le danger de ne pas utiliser
onSaveInstanceState
et l'utilisation de la mémoire est le danger de l'Android à la reconquête de la mémoire. Sauvé de l'état ne seraient pas touchés par cela, mais à l'aide de variables d'instance ou cachés fragments entraînerait une perte de données.Si
savedStateInstance
est nul, il n'est pas en état de restauration.La
if (values != null)
est tout simplement pour se prémunir contre la possibilité qu'aucun tableau n'a été enregistré, mais si vous le code de votre ArrayAdapter pour gérer un null ensemble de données, vous n'aurez pas besoin de cela.La solution ultime, si vos lignes sont des instances de l'une de vos propres classes et non pas dans un seul des éléments de données, est de mettre en œuvre l'interface Parcelable sur cette classe, vous pouvez utiliser
savedState.putParcelableArray("myKey", myArray)
. Vous seriez surpris de voir combien il est utile de savoir comment mettre en œuvre Parcelable - il vous permet de passer vos classes à l'intérieur d'intentions et vous permet d'écrire beaucoup plus propre code."mykey"
Lors de la rotation de l'appareil, l'application est redémarrée. Donc
onSaveInstance
est appelée avant que l'application est détruit. Vous pouvez économiser de l'adaptateur tableau deonSaveInstance
et lorsque leonCreate
est enfin appelée lorsque l'application est lancée à nouveau, vous pouvez récupérer le tableau de l'adaptateur et de le régler à la vue de la liste.Il est assez facile de sauvegarder les données de votre Carte dans
onSaveInstance
.Maintenant, vous devez enregistrer l'emplacement (Scroll). Vous pouvez le faire
la voie de la facilité
Puisque la modification de screenOrientation va gâcher les choses de toute façon, vous pouvez vous permettre quelques marginaux d'erreur et simplement, dans votre
onSaveInstance
, enregistrez le premier élément visible à l'aide delistView.getFirstVisiblePosition()
.Puis dans votre
onRestoreInstance
vous pouvez récupérer cet indice pour faire défiler jusqu'à l'élément de même à l'aide delistview.setSelection(position)
. Bien sûr, vous pouvez utiliserlistview.smoothScrollToPosition(position)
mais ce serait bizarre.à la dure
Avoir plus exacte de la position, vous aurez besoin de descendre plus 1 niveau: Obtenir la position de défilement (pas d'index) et enregistrer cette position. Puis, après restauration, de revenir à cette position. Dans votre
onSaveInstance
, enregistrer la position retournée à partir delistview.getScrollY()
. Lorsque vous récupérez cette position dans votreonRestoreInstance
, vous pouvez revenir à cette position à l'aide delistview.scrollTo(0, position)
.Pourquoi est-il vraiment un moyen dur?
Simple. Vous ne sera probablement pas en mesure de revenir à cette position, car votre listview n'auront pas passé la mesure et la mise en page encore. Vous pouvez résoudre ce problème en attendant la mise en page après le réglage de l'adaptateur à l'aide
getViewObserver().addOnGlobalLayoutListener
. Dans cette fonction de rappel, de poster un exécutable pour faire défiler jusqu'à la position.Je le conseil à l'utilisation de la première "voie facile", car en général lorsque l'orientation de l'écran a été changé à l'utilisateur va probablement bouger ses doigts en arrière. Nous avons juste besoin de lui montrer les mêmes éléments "ou".
lorsque les changements d'orientation de l'activité du cycle de vie des appels
onPause
et puisonRestart
Faire quelque chose comme cela -
onPause()
etonRestart()
et le journal d'impression sur eux et voir ce qui se passe.Je ne connais pas le contenu de votre
ArrayAdapter
ou laList
sauvegarde, mais ce que sur la sauvegarde de données de la liste serializable, l'enregistrer, puis de le charger lorsque la vue est recréé?Traditionnellement que j'ai vu cette appraoch utilisé lorsque vous tentez de stocker des données lorsque l'application est en cours de fermeture ou de risques d'être tué à l'arrière-plan. Il y a une grande post sur la sérialisation complet avec des exemples de code ici. Ils marchent à travers la prise d'un
ArrayList
d'objets personnalisés, l'écrire dans un fichier et de le rouvrir plus tard. Je pense que si vous avez mis en œuvre cette approche, d'écrire les données de votre sauvegardeList
ouArrayAdapter
dansonPause()
avant l'activité est détruite, vous pouvez recharger ce fichier lors de la activtivy est recréé.D'autres approches (a/k/a) plans de sauvegarde):
(1) Facile, mais bâclée - Si votre liste est quelques primative, comme une liste de chaînes, vous pouvez toujours envisager d'écrire les valeurs individuellement à
SharedPreferences
et la récupération sur le recharger. Juste être sûr d'attribuer des id unique dans la procédure de sauvegarde.NOTE alors que cela peut fonctionner,
SharedPreferecnes
est généralement pas conçu pour gérer de grandes quantités de données, donc si vous êtes à la liste est longue, je vous conseille d'éviter cette approche. Pour un peu de points de données, cependant, je ne le vois pas être un problème.(2) un peu plus difficile, mais risqué - Si vous êtes
List
la sauvegarde de l'adaptateur contient des objets qui implémententparcelable
ou sont déjà serializable, envisager l'adoption de laList
via unIntent
à une activité existante qui est en arrière-plan, et en utilisant une fonction de rappel pour récupérer des données lorsque l'activité est recréée. Ceci est similaire à votre idée de création d'un fondFragment
. Les deux approches courent le risque que laActivity
ouFragment
vous ciblez ne sera pas là.Pour enregistrer des données pour l'affichage de la liste de ne pas recharger encore et encore pendant le fragment de loisirs est à enregistrer que les données d'un membre statique d'une classe.
Quelque chose comme
Et puis, à partir de l'adaptateur d'abord charger les données à partir d'internet ou à partir de la base de données locale
définissez ensuite extraites des données membres statiques quelque chose comme ceci:
et puis dans votre onResume méthode de mise à jour de ces valeurs à l'adaptateur quelque chose comme:
ceci peut être utilisé pour enregistrer tout type de données pour une seule session
onSaveInstanceState
méthode dans votre Fragment.