Как вставить дополнительные элементы в SimpleCursorAdapter или Cursor для Spinner? - PullRequest
30 голосов
/ 20 июля 2011

У меня есть Spinner, который должен показать список данных, извлеченных из базы данных. Данные возвращаются курсору из запроса, и курсор передается в SimpleCursorAdapter счетчика. Он работает нормально, но я хочу вставить еще один элемент поверх этих данных. Например, счетчик уже показывает список созданных пользователем шаблонов, сохраненных в БД, но я хочу вставить «Новый шаблон» и «Пустой шаблон» поверх списка шаблонов, и его необходимо вставить в Cursor / SimpleCursorAdapter. каким-то образом.

Я рассмотрел использование arraylist и заполнение arraylist из курсора, но курсор является лучшим решением для меня, так как он также содержит другие связанные строки данных. Я искал в Интернете другие решения и нашел несколько ответов, в которых просил использовать CursorWrapper для этой цели, но не смог найти конкретный пример того, как использовать CursorWrapper для достижения того, чего я хочу. Как я могу вставить несколько строк в курсор или кто-то может дать простой пример следовать CursorWrapper! Заранее спасибо.

Ответы [ 4 ]

90 голосов
/ 31 января 2013

Вы можете использовать комбинацию 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 голосов
/ 30 сентября 2014

Я попробовал решение, предоставленное @naktinis, но результат оказался не таким, как я ожидал. Чего я сам хотел добиться в качестве адаптера, в который можно добавлять новые элементы вверху (индекс 0). Однако, учитывая данное решение, новые элементы действительно были добавлены сверху, но только в КОНЕЦ MatrixCursor. Другими словами, когда я динамически добавлял строки в «дополнительные» 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;
  }
}
2 голосов
/ 14 января 2014

Это метод, который я попробовал.

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.

0 голосов
/ 14 января 2012

Я нашел некоторую информацию о добавлении элемента в спиннер, который имеет SimpleCursorAdapter: http://groups.google.com/group/android-developers/browse_thread/thread/4123868e02fc9172

...