2011-01-08 2 views
0

Dans mon application, j'ai une base de données SQLite qui ressemble à ceci:Affichage des données dans un ListView lorsque chaque objet est situé sur plus d'une ligne dans un curseur

CREATE TABLE notes (_id integer primary key, 
        content text); 
CREATE TABLE tags (_id integer primary key, 
        name text, 
        noteid integer, 
        foreign key(noteid) references notes(_id)); 

Je stocker du texte qui peut avoir une certaine tags associés. Maintenant, je veux montrer ce texte et les balises dans un ListView. Cependant, je ne peux pas comprendre comment faire cela avec un SimpleCursorAdapter. Est-ce même possible? Mes données pourraient ressembler à ceci:

sqlite> select * from notes; 
1|foo bar baz 
sqlite> select * from tags; 
1|x|1 
2|y|1 

La requête pour obtenir toutes les notes et les données qu'il retourne ressemble à ceci:

sqlite> select notes._id, notes.content, tags.name from notes, tags where notes._id = tags.noteid; 
1|foo bar baz|x 
1|foo bar baz|y 

Maintenant, si je veux lier ces données à la ListView dans certains façon, comment le faire? Je serais heureux si chaque ligne int le ListView contenait deux lignes, une ligne avec le contenu et une ligne avec tous les tags. Ai-je raison de deviner que le SimpleCursorAdapter ne m'aidera pas ici? Que devrais-je faire à la place?

Répondre

1

SimpleCursorAdapter seul ne peut pas vous aider ici. Si votre but est que vous vouliez qu'une ligne soit une note + toutes ses étiquettes, vous pouvez essayer de surcharger bindView() en SimpleCursorAdapter et de verser les étiquettes de cette façon. Cela impliquerait que vous avez déjà construit une sorte de balises note-> et que vous pouvez donc rapidement déterminer les balises à insérer dans la ligne.

Pour construire la HashMap, vous avez deux choix que je vois:

  1. les construire à la volée en regardant la note dans le HashMap, puis en faisant une requête pour obtenir les tags pour cette note si elles ne sont pas trouvées, les mettre en cache dans le HashMap pour les réutiliser plus tard (par exemple, en faisant défiler). Le hic ici est que vous faites un tas de petites requêtes (mauvaises) et les faites sur le thread de l'application principale pendant que l'utilisateur défile (vraiment mauvais).

  2. Est-ce une grande requête en utilisant une clause IN pour obtenir tous les tags pour toutes les notes, et convertir les Cursor résultant en une HashMap entièrement peuplée. Ensuite, vos recherches par ligne vont toutes réussir. Cela fonctionne bien si vous avez seulement un nombre modeste de lignes; Dans le cas contraire, cette requête peut prendre plus de temps que la patience de l'utilisateur.

Si votre schéma est flexible, vous pourriez envisager si vous êtes mieux servis avec une certaine quantité de dénormalisation, comme ayant les étiquettes dans une seule colonne de la table notes via une liste délimitée par des virgules ou quelque chose. Même si cela complique les opérations d'écriture (par exemple, mettre des balises à deux endroits), si vos lectures dépassent largement vos écritures, cela peut en valoir la peine.

+0

Ce sont tous de bons points. Qu'en est-il de sublimer un adaptateur pour gérer cela pour moi? Celui qui lit le nombre approprié de lignes pour chaque objet note. – Arlaharen

+0

@Arlaharen: Il n'y a pas de classe adaptateur intégrée qui a la notion de traverser les relations de cette façon. Sinon, toute ma réponse ci-dessus implique de "sous-classer un adaptateur". – CommonsWare

Questions connexes