Рекомендации по проектированию ListAdapter андроид


Я хочу написать для Android ListAdapter для предоставления данных из базы данных, которые выглядят так:

CREATE TABLE note (_id integer primary key autoincrement,
                   content text not null)
CREATE TABLE tag (_id integer primary key autoincrement,
                  name text not null);
CREATE TABLE relation (_id integer primary key autoincrement,
                       noteid integer not null,
                       tagid integer not null,
                       idx integer not null);

Я использую эту базу данных, чтобы хранить заметки и связанные с ними теги, как упорядоченный список. Одно требование ListAdapter заключается в том, что он должен быть в состоянии обновить содержимое списка при изменении базовых данных. Я могу запросить все записи в базе данных с помощью этого запроса:

SELECT note._id AS noteid, 
       note.content, 
       relation.idx AS tagidx,
       tag.name
FROM note
LEFT JOIN relation ON (relation.noteid = note._id)
LEFT JOIN tag ON (tag._id = relation.tagid)
ORDER BY noteid, tagidx;

Что даст мне результаты в таком виде (нулевые значения показаны для ясности):

0|foo bar baz|0|x
1|hello world|null|null
2|one more nn|0|yy
2|one more nn|1|y

Как видите, с более чем один тег будет располагаться на более чем одну строку в результате. Это означает, что я не могу смотреть на размер курсора, чтобы определить количество нот, я должен пройти весь курсор, чтобы получить граф. Я не хочу этого делать.

Решение я придумать так далеко, чтобы использовать два курсора: один с запрос, упомянутые выше, и один с запрос, содержащий количество строк в примечаниях таблицы (выбрать количество(*) из заметки). В конструкторе я называю intializeCursors():

private void initializeCursors() {
    notesCursor.moveToFirst();
    countCursor.moveToFirst();
    count = countCursor.getInt(0);
}

Я реализовал метод getitem() такой:

public Note getItem(int position) {
    // notes is a List of notes that we have already read.
    if (position < notes.size()) { 
        return notes.get(position);
    }

    int cursorPosition = notes.size();
    while (cursorPosition <= position) {
        // Creates a note by reading the correct number of rows.
        Note note = NotesDb.noteFrom(notesCursor); 
        notes.add(note);
        ++cursorPosition;
    }
    return notes.get(position);
}

Адаптер предполагает, что курсоры управляются некоторые действия , которые назвал startManagingCursor() на них.

Пока все хорошо, я думаю. Проблема теперь, как обрабатывать курсор requeried. Так как у меня два курсора мне нужно зарегистрировать слушателя для них обоих, и когда я получил onChange, после() для обоих из них я могу initializeCursors() и сообщать о любых слушателей, зарегистрированных на мое ListAdapter изменения в свои данные.

Сценарий обновление является фактической причиной того, что я нуждался в двух курсоров, в первую очередь. Я не понял, как пересчитать количество купюр в нужный курсор, не просим базу данных с помощью другого курсора.

Это лучшее, что я до сих пор. Я хочу проверить вменяемость этого подхода с этой группой. :-) Это два курсора подход слишком сложен? Возможно, я пропустил некоторые части API, который решает это красиво для меня?



910
6
задан 28 января 2011 в 07:01 Источник Поделиться
Комментарии