Как вставить дополнительные элементы в SimpleCursorAdapter или Cursor для Spinner?
У меня есть Spinner, который должен отображать список данных, полученных из базы данных. Данные возвращаются курсору из запроса, и курсор передается в spinner SimpleCursorAdapter. Он отлично работает как таковой, но я хочу вставить еще один элемент поверх этих данных. Например, счетчик уже показывает список созданных пользователем шаблонов, сохраненных в БД, но я хочу вставить "Новый шаблон" и "Пустой шаблон" поверх списка шаблонов, и его необходимо вставить в Cursor/SimpleCursorAdapter каким-то образом.
Я рассмотрел использование arraylist и заполнение arraylist курсором, но курсор - лучшее решение для меня, так как оно содержит другие связанные строки данных. Я искал интернет для других решений и нашел некоторые ответы, предлагая использовать CursorWrapper для этой цели, но я не смог найти конкретный пример того, как использовать CursorWrapper для выполнения того, что я хочу. Как я могу вставить некоторые строки в курсор, или кто-то, пожалуйста, дайте простой пример CursorWrapper! Спасибо заранее.
Ответы
Ответ 1
Вы можете использовать комбинацию MergeCursor
и MatrixCursor
с вашим DB cursor
следующим образом:
MatrixCursor extras = new MatrixCursor(new String[] { "_id", "title" });
extras.addRow(new String[] { "-1", "New Template" });
extras.addRow(new String[] { "-2", "Empty Template" });
Cursor[] cursors = { extras, cursor };
Cursor extendedCursor = new MergeCursor(cursors);
Ответ 2
Это метод, который я пробовал.
MatrixCursor m = new MatrixCursor(c.getColumnNames());
Cursor c = DBHelper.rawQuery("Select values from your_table");
MatrixCursor m = new MatrixCursor(c.getColumnNames());
//Use MatrixCursor#addRow here to add before the original cursor
while (c.moveToNext()) {
//Use MatrixCursor#addRow here to add before the original row
DBHelper.insertRow(c, m);
//Use MatrixCursor#addRow here to add after the original row
}
//Use MatrixCursor#addRow here to add after the original cursor
m.addRow(new String[]{col1Val, col2Val, col3Val,..., //to match the number of columns needed});
DBHelper.insertRow()
public final static void insertRow(Cursor from, MatrixCursor to) {
final String columns[] = from.getColumnNames(), values[] = new String[columns.length];
final int size = columns.length;
for (int i = 0; i < size; i++) {
values[i] = getStringFromColumn(from, columns[i]);
}
to.addRow(values);
}
С помощью этого метода вы можете добавить любое количество строк в любом месте вашего курсора. Несмотря на то, что он не использует CursorWrapper, его можно использовать с CursorAdapters или SimpleCursorAdapters.
Ответ 3
Я попробовал решение, предоставленное @naktinis, но результат не был тем, что я ожидал. То, что я сам хотел достичь в качестве адаптера, в который можно добавить новые элементы вверху (индекс 0). Однако с учетом данного решения новые элементы были действительно добавлены сверху, но только к END MatrixCursor. Другими словами, когда я динамически добавлял строки в MatrixCursor "extras" , у меня было что-то вроде этого:
- "extras" строка 1
- "extras" строка 2
- "extras" строка 3
- "курсор" строка 1
- "курсор" строка 2
- "курсор" строка 3.
Однако то, чего я действительно хотел достичь, было примерно так:
- "extras" строка 3
- "extras" строка 2
- "extras" строка 1
- "курсор" строка 1
- "курсор" строка 2
- "курсор" строка 3.
Другими словами, самые последние элементы вводятся вверху (индекс 0).
Я смог добиться этого вручную, выполнив следующее. Обратите внимание, что я не включал никакой логики для динамического удаления элементов из адаптера.
private class CollectionAdapter extends ArrayAdapter<String> {
/**
* This is the position which getItem uses to decide whether to fetch data from the
* DB cursor or directly from the Adapter underlying array. Specifically, any item
* at a position lower than this offset has been added to the top of the adapter
* dynamically.
*/
private int mCursorOffset;
/**
* This is a SQLite cursor returned by a call to db.query(...).
*/
private Cursor mCursor;
/**
* This stores the initial result returned by cursor.getCount().
*/
private int mCachedCursorCount;
public Adapter(Context context, Cursor cursor) {
super(context, R.layout.collection_item);
mCursor = cursor;
mCursorOffset = 0;
mCachedCursorCount = -1;
}
public void add(String item) {
insert(item, 0);
mCursorOffset = mCursorOffset + 1;
notifyDataSetChanged();
}
@Override
public String getItem(int position) {
// return the item directly from underlying array if it was added dynamically.
if (position < mCursorOffset) {
return super.getItem(position);
}
// try to load a row from the cursor.
if (!mCursor.moveToPosition(position - mCursorOffset)) {
Log.d(TAG, "Failed to move cursor to position " + (position - mCursorOffset));
return null; // this shouldn't happen.
}
return mCursor.getString(INDEX_COLLECTION_DATA);
}
@Override
public int getCount() {
if (mCachedCursorCount == -1) {
mCachedCursorCount = mCursor.getCount();
}
return mCursorOffset + mCachedCursorCount;
}
}
Ответ 4
Я нашел некоторую информацию о добавлении элемента в spinner, который имеет SimpleCursorAdapter:
http://groups.google.com/group/android-developers/browse_thread/thread/4123868e02fc9172