如何将额外元素插入到 SimpleCursorAdapter 或 Spinner 的光标中?
Posted
技术标签:
【中文标题】如何将额外元素插入到 SimpleCursorAdapter 或 Spinner 的光标中?【英文标题】:How to insert extra elements into a SimpleCursorAdapter or Cursor for a Spinner? 【发布时间】:2011-10-08 22:59:30 【问题描述】:我有一个 Spinner,用于显示从数据库中获取的数据列表。数据从查询返回到游标,游标被传递给微调器的 SimpleCursorAdapter。它工作正常,但我想在这个数据之上插入另一个项目。例如,微调器已经显示了保存在数据库中的用户创建模板列表,但我想在模板列表顶部插入“新模板”和“空模板”,并且需要将其插入 Cursor/SimpleCursorAdapter不知何故。
我考虑过使用数组列表并从游标填充数组列表,但游标对我来说是更好的解决方案,因为它也包含其他相关的数据行。我在互联网上搜索了其他解决方案,并找到了一些要求为此目的使用 CursorWrapper 的答案,但我找不到如何使用 CursorWrapper 来完成我想要的具体示例。如何在光标中插入一些行,或者有人可以给出一个易于遵循的 CursorWrapper 示例!提前致谢。
【问题讨论】:
【参考方案1】:您可以将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);
【讨论】:
太棒了。这比像其他人建议的那样将光标加载到数组列表中要好得多。谢谢。 是否需要关闭extras
和cursor
游标?【参考方案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)。但是,在给出解决方案的情况下,确实在顶部添加了新元素,但仅添加到了 MatrixCursor 的 END。换句话说,当我将行动态添加到“附加”MatrixCursor 时,我得到了这样的结果:
“附加”行1 “附加”行2 “附加”行 3 “光标”第 1 行 “光标”第 2 行 “光标”第 3 行。但是,我真正想要实现的是这样的:
“附加”行 3 “附加”行2 “附加”行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'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;
【讨论】:
以上是关于如何将额外元素插入到 SimpleCursorAdapter 或 Spinner 的光标中?的主要内容,如果未能解决你的问题,请参考以下文章