J'essaie de déterminer la meilleure façon d'avoir un seul ListView qui contient différentes dispositions pour chaque ligne. Je sais comment créer une ligne personnalisée + un adaptateur de tableau personnalisé pour prendre en charge une ligne personnalisée pour la vue de liste entière, mais comment puis-je implémenter de nombreux styles de ligne différents dans ListView?
android
listview
listviewitem
w.donahue
la source
la source
Réponses:
Puisque vous savez combien de types de disposition vous auriez, il est possible d'utiliser ces méthodes.
getViewTypeCount()
- cette méthode retourne des informations combien de types de lignes avez-vous dans votre listegetItemViewType(int position)
- renvoie des informations sur le type de mise en page que vous devez utiliser en fonction de la positionEnsuite, vous gonflez la disposition uniquement si elle est nulle et déterminez le type à l'aide
getItemViewType
.Regardez ce tutoriel pour plus d'informations.
Pour réaliser quelques optimisations de structure que vous avez décrites dans le commentaire, je suggère:
ViewHolder
. Cela augmenterait la vitesse car vous n'aurez pas à appeler àfindViewById()
chaque fois dans lagetView
méthode. Voir List14 dans les démonstrations d'API .J'espère que cela vous aidera. Si vous pouviez fournir un stub XML avec votre structure de données et des informations sur la façon exacte dont vous souhaitez le mapper en ligne, je serais en mesure de vous donner des conseils plus précis. Par pixel.
la source
Vous connaissez déjà les bases. Il vous suffit d'obtenir votre adaptateur personnalisé pour renvoyer une disposition / vue différente en fonction des informations de ligne / curseur fournies.
A
ListView
peut prendre en charge plusieurs styles de ligne car il dérive de AdapterView :Si vous regardez l' adaptateur , vous verrez des méthodes qui tiennent compte de l'utilisation des vues spécifiques aux lignes:
Les deux dernières méthodes fournissent la position afin que vous puissiez l'utiliser pour déterminer le type de vue que vous devez utiliser pour cette ligne .
Bien sûr, vous n'utilisez généralement pas AdapterView et Adapter directement, mais utilisez plutôt ou dérivez d'une de leurs sous-classes. Les sous-classes de l'adaptateur peuvent ajouter des fonctionnalités supplémentaires qui changent la façon d'obtenir des dispositions personnalisées pour différentes lignes. Étant donné que la vue utilisée pour une ligne donnée est pilotée par l'adaptateur, l'astuce consiste à obtenir que l'adaptateur renvoie la vue souhaitée pour une ligne donnée. La procédure à suivre varie en fonction de l'adaptateur spécifique.
Par exemple, pour utiliser ArrayAdapter ,
getView()
pour gonfler, remplir et retourner la vue souhaitée pour la position donnée. LegetView()
procédé comprend une vue de réutilisation d'opportunité via leconvertView
paramètre.Mais pour utiliser des dérivés de CursorAdapter ,
newView()
pour gonfler, remplir et renvoyer la vue souhaitée pour l'état actuel du curseur (c'est-à-dire la "ligne" actuelle) [vous devez également remplacerbindView
afin que le widget puisse réutiliser les vues]Cependant, pour utiliser SimpleCursorAdapter ,
SimpleCursorAdapter.ViewBinder
avec unesetViewValue()
méthode pour gonfler, remplir et renvoyer la vue souhaitée pour une ligne donnée (état actuel du curseur) et une "colonne" de données. La méthode peut définir uniquement les vues "spéciales" et s'en remettre au comportement standard de SimpleCursorAdapter pour les liaisons "normales".Recherchez les exemples / tutoriels spécifiques pour le type d'adaptateur que vous finissez par utiliser.
la source
BaseAdapter
. Dériver de BaseAdapter serait le plus "flexible", mais serait le pire en matière de réutilisation et de maturité du code car il ne tire pas parti des connaissances et de la maturité déjà mises dans les autres adaptateurs.BaseAdapter
est là pour les contextes non standard où les autres adaptateurs ne correspondent pas.CursorAdapter
etSimpleCursorAdapter
.ArrayAdapter
, peu importe la disposition que vous donnez au constructeur, tant qu'ilgetView()
gonfle et renvoie le bon type de dispositiongetViewTypeCount()
n'est déclenché qu'une seule fois à chaque appelListView.setAdapter()
, pas pour chaque foisAdapter.notifyDataSetChanged()
.Jetez un oeil dans le code ci-dessous.
Tout d'abord, nous créons des dispositions personnalisées. Dans ce cas, quatre types.
even.xml
odd.xml
white.xml
black.xml
Ensuite, nous créons l'élément listview. Dans notre cas, avec une chaîne et un type.
Après cela, nous créons un support de vue. Il est fortement recommandé car Android OS conserve la référence de mise en page pour réutiliser votre élément lorsqu'il disparaît et réapparaît à l'écran. Si vous n'utilisez pas cette approche, chaque fois que votre élément apparaît sur l'écran, le système d'exploitation Android en crée un nouveau et provoque une fuite de mémoire de votre application.
Enfin, nous créons notre adaptateur personnalisé remplaçant getViewTypeCount () et getItemViewType (int position).
Et notre activité est quelque chose comme ça:
créez maintenant une liste dans le fichier mainactivity.xml comme ceci
la source
Dans votre adaptateur de tableau personnalisé, vous remplacez la méthode getView (), comme vous le savez probablement. Ensuite, tout ce que vous avez à faire est d'utiliser une instruction switch ou une instruction if pour renvoyer une certaine vue personnalisée en fonction de l'argument position transmis à la méthode getView. Android est intelligent en ce qu'il ne vous donnera qu'une convertView du type approprié pour votre position / ligne; vous n'avez pas besoin de vérifier qu'il est du type correct. Vous pouvez aider Android avec cela en remplaçant les méthodes getItemViewType () et getViewTypeCount () de manière appropriée.
la source
Si nous devons afficher un type de vue différent dans la vue de liste, il est bon d'utiliser getViewTypeCount () et getItemViewType () dans l'adaptateur au lieu de basculer une vue VIEW.GONE et VIEW.VISIBLE peut être une tâche très coûteuse dans getView () qui affecter le défilement de la liste.
Veuillez vérifier celui-ci pour l'utilisation de getViewTypeCount () et getItemViewType () dans l'adaptateur.
Lien: l'utilisation-de-getviewtypecount
la source
ListView a été conçu pour des cas d'utilisation simples comme la même vue statique pour tous les éléments de ligne.
Étant donné que vous devez créer des ViewHolders et utiliser de manière significative
getItemViewType()
et afficher dynamiquement différents XML de disposition d'élément de ligne, vous devriez essayer de le faire en utilisant RecyclerView , qui est disponible dans l'API Android 22. Il offre un meilleur support et une meilleure structure pour plusieurs types de vues.Consultez ce tutoriel sur la façon d'utiliser RecyclerView pour faire ce que vous recherchez.
la source