我有一个Spinner,用于显示从数据库中获取的数据列表。数据从查询返回到游标,并将光标传递给spinner的SimpleCursorAdapter。这样工作正常,但我想在这些数据之上插入另一个项目。例如,微调器已经显示了保存在DB中的用户创建模板列表,但我想在模板列表的顶部插入“新模板”和“空模板”,并且需要将其插入到Cursor / SimpleCursorAdapter中不知。
我考虑过使用arraylist并从游标中填充arraylist,但是光标对我来说是更好的解决方案,因为它也包含其他相关的数据行。我搜索了互联网的其他解决方案,并找到了一些要求使用CursorWrapper的答案,但我找不到一个具体的例子如何使用CursorWrapper来实现我想要的。如何在光标中插入一些行或者有人可以给出一个易于遵循的CursorWrapper示例!提前谢谢。
答案 0 :(得分:89)
您可以将MergeCursor
和MatrixCursor
与您的数据库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);
答案 1 :(得分: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一起使用。
答案 2 :(得分:2)
我尝试了@naktinis提供的解决方案,但结果并非我的预期。我自己想要实现的是一个可以在顶部添加新元素的适配器(索引0)。但是,根据给出的解决方案,确实在顶部添加了新元素,但仅添加到MatrixCursor的END。换句话说,当我动态地将行添加到&#34; extras&#34; MatrixCursor,我有这样的事情:
然而,我真正想要实现的是这样的:
换句话说,最近的元素进入顶部(索引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's 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;
}
}
答案 3 :(得分:0)
我找到了一些关于向具有SimpleCursorAdapter的spinner添加元素的信息: http://groups.google.com/group/android-developers/browse_thread/thread/4123868e02fc9172