How to insert extra elements into a SimpleCursorAdapter or Cursor for a Spinner? How to insert extra elements into a SimpleCursorAdapter or Cursor for a Spinner? android android

How to insert extra elements into a SimpleCursorAdapter or Cursor for a Spinner?


You can use a combination of MergeCursor and MatrixCursor with your DB cursor like this:

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


This is the method I tried.

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 cursorwhile (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 cursorm.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);}

With this method, you can add any amount of rows anywhere in your cursor. Even though it is not making use of CursorWrapper, it can be used with CursorAdapters or SimpleCursorAdapters.


I tried the solution provided by @naktinis, but the result wasn't what I expected. What I myself wanted to achieve as an adapter in which new elements can be added at the top (index 0). However, with the solution given, new elements were indeed added at the top but only to the END of the MatrixCursor. In other words, when I added rows dynamically to the "extras" MatrixCursor, I got something like this:

  • "extras" row 1
  • "extras" row 2
  • "extras" row 3
  • "cursor" row 1
  • "cursor" row 2
  • "cursor" row 3.

However, what I really wanted to achieve was something like this:

  • "extras" row 3
  • "extras" row 2
  • "extras" row 1
  • "cursor" row 1
  • "cursor" row 2
  • "cursor" row 3.

In other words, most recent elements enter at the top (index 0).

I was able to achieve this manually by doing the follow. Note that I did not include any logic to handle dynamically removing elements from the adapter.

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