Mostrar datos en un ListView cuando cada objeto está ubicado en más de una fila en un Cursor

En mi aplicación tengo una base de datos sqlite que se ve así:

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));

Estoy almacenando texto que puede tener algunas etiquetas asociadas. Ahora quiero mostrar este texto y las etiquetas en un ListView. Sin embargo, no puedo averiguar cómo hacer esto con un SimpleCursorAdapter. ¿Es siquiera posible? Mis datos pueden verse así:

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

La consulta para obtener todas las notas y los datos que devuelve se ve así:

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

Ahora, si quiero vincular estos datos al ListView de alguna manera, ¿cómo hacerlo? Sería feliz si cada fila en el ListView contenía dos líneas, una línea con el contenido y una línea con todas las etiquetas. ¿Estoy en lo cierto al suponer que SimpleCursorAdapter no me ayudará aquí? ¿Qué debo hacer en su lugar?

preguntado el 08 de enero de 11 a las 22:01

1 Respuestas

SimpleCursorAdapter solo no puedo ayudarte aquí.

Si su objetivo es que desee que una fila sea una nota + todas sus etiquetas, puede intentar anular bindView() in SimpleCursorAdapter y vertiendo las etiquetas de esa manera. Eso implicaría que ya ha construido algún tipo de HashMap de nota-> etiquetas y, por lo tanto, puede determinar rápidamente las etiquetas que deben ir en la fila.

Para construir el HashMap, tienes dos opciones que veo:

  1. Constrúyalos sobre la marcha buscando la nota en el HashMapy, a continuación, realizar una consulta para obtener las etiquetas de esa nota si no se encuentran, almacenarlas en la memoria caché HashMap para su reutilización posterior (p. ej., desplazamiento). El problema aquí es que estás haciendo un montón de consultas pequeñas (malas) y las haces en el hilo principal de la aplicación mientras el usuario se desplaza (realmente mal).

  2. Haz una gran consulta usando un IN cláusula para obtener todas las etiquetas para todas las notas y convertir el resultado Cursor en un completamente poblado HashMap. Entonces, todas sus búsquedas por fila se realizarán correctamente. Esto funciona bien si solo tiene un número modesto de filas; de lo contrario, esta consulta puede tardar más de lo que el usuario tiene paciencia.

Si su esquema es flexible, podría considerar si se le sirve mejor con cierta cantidad de desnormalización, como tener las etiquetas en una sola columna de la tabla de notas a través de una lista delimitada por comas o algo así. Incluso si eso complica las operaciones de escritura (por ejemplo, poner etiquetas en dos lugares), si sus lecturas superan en gran medida a sus escrituras, puede valer la pena.

Respondido el 09 de enero de 11 a las 02:01

Todos esos son buenos puntos. ¿Qué hay de subclasificar algún adaptador para manejar esto por mí? Uno que lee el número apropiado de filas para cada objeto de nota. - Arlaharen

@Arlaharen: No hay una clase de adaptador incorporada que tenga la noción de atravesar relaciones de esta manera. De lo contrario, toda mi respuesta anterior implica "subclasificar algún adaptador". - CommonsWare

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.